package com.yonyou.cyxdms.basedata.service.service.product;

//import cn.hutool.core.lang.Assert;
//import com.baic.cms.ws.vehicle.client.dto.DTHEADER;
//import com.baic.cms.ws.vehicle.client.dto.cms008.Cms008ObjectFactory;
//import com.baic.cms.ws.vehicle.client.dto.cms008.DTCMS008RET;
//import com.baic.cms.ws.vehicle.client.dto.cms009.Cms009ObjectFactory;
//import com.baic.cms.ws.vehicle.client.dto.cms009.DTCMS009RET;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaoleilu.hutool.bean.BeanUtil;
import com.xiaoleilu.hutool.util.CollectionUtil;
import com.xiaoleilu.hutool.util.ObjectUtil;
import com.xiaoleilu.hutool.util.StrUtil;
import com.yonyou.cyx.framework.bean.dto.framework.RestResultResponse;
import com.yonyou.cyx.framework.bean.dto.framework.ResultBean;
import com.yonyou.cyx.framework.compent.redis.RedisClient;
import com.yonyou.cyx.framework.service.excel.ExcelDataType;
import com.yonyou.cyx.framework.service.excel.ExcelExportColumn;
import com.yonyou.cyx.framework.service.excel.ExcelGenerator;
import com.yonyou.cyx.framework.util.bean.ApplicationContextHelper;
import com.yonyou.cyx.function.constants.FunctionConstants;
import com.yonyou.cyx.function.exception.ServiceBizException;
import com.yonyou.cyx.function.utils.bean.BeanMapperUtil;
import com.yonyou.cyx.function.utils.common.StringUtils;
import com.yonyou.cyx.function.utils.jsonserializer.JSONUtil;
import com.yonyou.cyxdms.basedata.client.constants.BaseDataCommonConstants;
import com.yonyou.cyxdms.basedata.client.constants.BaseDataDictConstants;
import com.yonyou.cyxdms.basedata.client.domains.vo.*;
import com.yonyou.cyxdms.basedata.client.dto.option.VsOptionDTO;
import com.yonyou.cyxdms.basedata.client.dto.product.TtVsPlanTemplateDTO;
import com.yonyou.cyxdms.basedata.client.dto.product.VehicleInfoDTO;
import com.yonyou.cyxdms.basedata.client.dto.wholesales.PlanTemplateDTO;
import com.yonyou.cyxdms.basedata.service.constant.BasedataCommonConstants;
import com.yonyou.cyxdms.basedata.service.constant.BasedataDictConstants;
import com.yonyou.cyxdms.basedata.service.dto.*;
import com.yonyou.cyxdms.basedata.service.dto.outapi.CmsApp04;
import com.yonyou.cyxdms.basedata.service.dto.outapi.CmsApp04Data;
import com.yonyou.cyxdms.basedata.service.dto.outapi.CmsApp04QueryDto;
import com.yonyou.cyxdms.basedata.service.dto.sap.CMS008ReqDTO;
import com.yonyou.cyxdms.basedata.service.dto.sap.CMS009ReqDTO;
import com.yonyou.cyxdms.basedata.service.dto.sap.CMSVHCL003ReqDTO;
import com.yonyou.cyxdms.basedata.service.dto.vehiclemaster.VehicleMasterInfoDTO;
import com.yonyou.cyxdms.basedata.service.dto.vehiclemodel.GeneralVsProductDTO;
import com.yonyou.cyxdms.basedata.service.dto.vehiclemodel.ProductQueryDTO;
import com.yonyou.cyxdms.basedata.service.entity.basedata.SystemParamPO;
import com.yonyou.cyxdms.basedata.service.entity.brand.BrandPO;
import com.yonyou.cyxdms.basedata.service.entity.color.ColorPO;
import com.yonyou.cyxdms.basedata.service.entity.configurer.PackagePO;
import com.yonyou.cyxdms.basedata.service.entity.model.ModelPO;
import com.yonyou.cyxdms.basedata.service.entity.option.VsOptionPO;
import com.yonyou.cyxdms.basedata.service.entity.product.VsProductPO;
import com.yonyou.cyxdms.basedata.service.entity.product.VsProductPricePO;
import com.yonyou.cyxdms.basedata.service.entity.productOption.VsProductOptionPO;
import com.yonyou.cyxdms.basedata.service.entity.sap.CMS008PO;
import com.yonyou.cyxdms.basedata.service.entity.sap.CMS009PO;
import com.yonyou.cyxdms.basedata.service.entity.sap.CMSVHCL003PO;
import com.yonyou.cyxdms.basedata.service.entity.series.SeriesPO;
import com.yonyou.cyxdms.basedata.service.feign.WholeSalesClient;
import com.yonyou.cyxdms.basedata.service.repository.basedata.CMS009Mapper;
import com.yonyou.cyxdms.basedata.service.repository.basedata.FuelPriceInfoMapper;
import com.yonyou.cyxdms.basedata.service.repository.basedata.ProductPriceDataMapper;
import com.yonyou.cyxdms.basedata.service.repository.color.ColorMapper;
import com.yonyou.cyxdms.basedata.service.repository.configurer.PackageMapper;
import com.yonyou.cyxdms.basedata.service.repository.model.ModelMapper;
import com.yonyou.cyxdms.basedata.service.repository.option.VsOptionMapper;
import com.yonyou.cyxdms.basedata.service.repository.product.VsProductMapper;
import com.yonyou.cyxdms.basedata.service.repository.product.VsProductPriceMapper;
import com.yonyou.cyxdms.basedata.service.repository.productOption.VsProductOptionMapper;
import com.yonyou.cyxdms.basedata.service.repository.series.SeriesMapper;
import com.yonyou.cyxdms.basedata.service.service.brand.BrandService;
import com.yonyou.cyxdms.basedata.service.service.option.VsOptionService;
import com.yonyou.cyxdms.basedata.service.service.series.SeriesService;
import com.yonyou.cyxdms.basedata.service.util.EasyPoiUtil;
import com.yonyou.cyxdms.basedata.service.util.MapUtils;
import com.yonyou.cyxdms.basedata.service.vo.*;
import com.yonyou.cyxdms.basedata.service.vo.model.ModelDictVO;
import com.yonyou.cyxdms.basedata.service.vo.packages.PackageDictVO;
import com.yonyou.cyxdms.basedata.service.vo.packages.VehicleProductPackageVO;
import com.yonyou.cyxdms.basedata.service.vo.productinfo.*;
import com.yonyou.cyxdms.basedata.service.vo.productinfo.VsProductVO;
import com.yonyou.cyxdms.basedata.service.vo.productprice.SaveProductPriceVO;
import com.yonyou.cyxdms.basedata.service.vo.series.SeriesDictVO;
import com.yonyou.cyxdms.framework.bean.dto.user_info.LoginInfoDto;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.MessageFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 定义车辆产品，一个车辆产品表示一类车辆，车辆产品定义即可以由车厂下发，也可以自定义 服务实现类
 * </p>
 *
 * @author renwd
 * @since 2019-01-18
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class VsProductServiceImpl extends ServiceImpl<VsProductMapper, VsProductPO> implements VsProductService {

    public static final Logger logger = LoggerFactory.getLogger(VsProductServiceImpl.class);

    @Resource
    private VsProductMapper vsProductMapper;

    @Resource
    private VsProductPriceMapper vsProductPriceMapper;

    @Resource
    private SeriesMapper seriesMapper;

    @Resource
    private ModelMapper modelMapper;

    @Resource
    private ColorMapper colorMapper;

    @Resource
    private PackageMapper packageMapper;

    @Resource
    private VsOptionMapper optionMapper;

    @Autowired
    private BrandService brandService;

    @Autowired
    private SeriesService seriesService;

    @Autowired
    private ExcelGenerator excelService;

    @Autowired
    private RedisClient redisClient;

    @Autowired
    private VsProductService vsProductService;

    @Autowired
    private VsProductOptionMapper vsProductOptionMapper;

//    @Autowired
//    private WsVehicleService wsVehicleService;

    @Autowired
    private CMS009Mapper cms009Mapper;

    @Autowired
    private VsOptionMapper vsOptionMapper;

    @Autowired
    private FuelPriceInfoMapper fuelPriceInfoMapper;
    @Autowired
    private VsOptionService vsOptionService;
    @Autowired
    private ProductPriceDataMapper productPriceDataMapper;

    /**
     * 根据五级车型查询销售指导价
     *
     * @param directivePriceDTO
     * @return com.yonyou.cyxdms.basedata.service.entity.product.SalesGuidancePriceVO
     * @author renwd
     * @since 2019/2/20
     */
    @Override
    public SalesGuidancePriceVO selectDirectivePrice(DirectivePriceDTO directivePriceDTO) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        directivePriceDTO.setOwnerCode(loginInfoDto.getOwnerCode());
        directivePriceDTO.setAppId(loginInfoDto.getAppId());
        return vsProductMapper.selectDirectivePrice(directivePriceDTO);
    }

    /**
     * 根据productId查询销售指导价
     *
     * @param productId
     * @return
     * @author ysj
     * @date 2019/09/16
     */
    @Override
    public SalesGuidancePriceVO selectDirectivePriceByProductId(Long productId) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        return vsProductMapper.selectDirectivePriceByProductId(loginInfoDto.getOwnerCode(), loginInfoDto.getAppId(), productId);
    }

    /**
     * 根据车系id检索车型信息
     *
     * @param serialId
     * @return (non - Javadoc)
     * @author Zhangsx
     * @date 2018年9月6日
     */
    @Override
    public List<CarparamVO> querySerial(Long serialId) {
        logger.debug("根据车系检索车型列表开始----111");
        LambdaQueryWrapper<VsProductPO> queryWrapper = new QueryWrapper<VsProductPO>().lambda();
        queryWrapper.eq(VsProductPO::getSeriesId, serialId);
        String appid = "ff7555e8ac239560";
        logger.debug("appid:{}", appid);
        queryWrapper.eq(VsProductPO::getAppId, appid);
        List<VsProductPO> list = vsProductMapper.selectList(queryWrapper);
        List<CarparamVO> vos = new ArrayList<>();
        for (VsProductPO carParamPo : list) {
            CarparamVO carparamVO = new CarparamVO();
            carparamVO.setCarInfo(carParamPo.getProductName());
            carparamVO.setModelId(carParamPo.getProductId().toString());
            //车型图片设为默认
            carparamVO.setCarImg("https://ss1.baidu.com/6ONXsjip0QIZ8tyhnq/it/u=3475957471,317830307&fm=58");
            vos.add(carparamVO);
        }
        return vos;
    }

    /**
     * 获取车型详细信息
     *
     * @param carId
     * @param colorId
     * @return com.yonyou.cyx.base.service.entity.carparam.CarBaseInfoVO
     * @author zhangsx
     * @since 2018/9/12
     */
    @Override
    public CarBaseInfoVO findCarInfo(Integer carId, Integer colorId) {

        Map<String, Object> map = new HashMap<>();
        map.put("carId", carId);
        map.put("colorId", colorId);

        return vsProductMapper.findCarInfo(map);
    }

    /**
     * 根据品牌id检索车系信息
     *
     * @param brandId
     * @return java.util.List<com.yonyou.cyx.base.service.entity.carserial.CarserialPO>
     * @author zhangsx
     * @since 2018/9/14
     */
    @Override
    public SerialVo querySerialInfo(Integer brandId) {
        logger.info("根据品牌Id检索车系信息开始:{}", brandId);
        //获取车列表信息
        LambdaQueryWrapper<SeriesPO> queryWrapper = new QueryWrapper<SeriesPO>().lambda();
        queryWrapper.eq(SeriesPO::getBrandId, brandId.longValue());

        String appId = "ff7555e8ac239560";
        logger.debug("appId:{}", appId);
        queryWrapper.eq(SeriesPO::getAppId, appId);

        //获取品牌名称
        LambdaQueryWrapper<BrandPO> brandWrapper = new QueryWrapper<BrandPO>().lambda();
        brandWrapper.eq(BrandPO::getBrandId, brandId.longValue());
        brandWrapper.eq(BrandPO::getAppId, appId);

        BrandPO carBrandPo = brandService.getOne(brandWrapper);
        List<SeriesCacheVO> carserialList = seriesService.getSeriesByBrandId(brandId.longValue());
        List<CarserialInfoVO> carSerialInfoVos = new ArrayList<>();
        for (SeriesCacheVO carserial : carserialList) {
            CarserialInfoVO carSerialInfoVO = new CarserialInfoVO();
            carSerialInfoVO.setCarserialId(carserial.getSeriesId());
            carSerialInfoVO.setName(carserial.getSeriesName());
            // DMS没有
            carSerialInfoVos.add(carSerialInfoVO);
        }
        //组装 返回H5的车系信息
        SerialVo serialVo = new SerialVo();
        serialVo.setBrandId(brandId);
        serialVo.setBrandName(carBrandPo.getBrandName());
        serialVo.setLogo("");
        serialVo.setSerialInfoList(carSerialInfoVos);
        return serialVo;
    }

    /**
     * 查询品牌车系车型配置信息
     *
     * @param queryCondition 查询条件
     * @return java.util.Map<java.lang.String, java.lang.Object>
     * @author renwd
     * @since 2018/11/26
     */
    @Override
    public Map<String, Object> queryModelByCondition(Map<String, Object> queryCondition) {
        return vsProductMapper.queryModelByCondition(queryCondition);
    }

    /**
     * 根据车系ID列表查询车型信息
     *
     * @author dengqiang
     * @since 2019/1/7
     */
    @Override
    public IPage<CarparamInfoVO> queryCarparamInfo(Long brandId, Long carserialId, Long pageNum, Long pageSize) {

        Page<CarparamInfoVO> page = new Page<>(pageNum, pageSize);

        List<CarparamInfoVO> carParamInfoVos = vsProductMapper.queryCarparam(brandId, carserialId);

        page.setRecords(carParamInfoVos);

        return page;
    }

    /**
     * 根据车系ID列表查询车型信息
     *
     * @author dengqiang
     * @since 2019/1/7
     */
    @Override
    public List<GroupCarparamInVO> queryCarparamInfo(Long carserialId) {
        // 根据车系id获取车型
        String appId = ApplicationContextHelper.getBeanByType(LoginInfoDto.class).getAppId();
        logger.info("参数列表：appId:{}", appId);
        // 查询系统参数表 - 车型转发URL
        SystemParamPO systemParamPo = brandService.queryRedirectUrl(appId, BasedataCommonConstants.QUERY_MODEL);
        if (systemParamPo != null) {
            String url = systemParamPo.getParamValue() + carserialId;
            String response = brandService.getRedirectResponse(appId, url);
            logger.info("response:-----------------{}", response);
            Map<String, Object> map = JSONUtil.jsonToMap(response);
            return JSONUtil.jsonToList(JSONUtil.objectToJson(map.get("data")), GroupCarparamInVO.class);
        } else {
            List<CarparamInVO> carParamInVos = vsProductMapper.queryCarparamInfo(carserialId, appId);
            return getCarparamInfo(carParamInVos);
        }
    }

    @Override
    public List<GroupCarparamInVO> getCarparamInfo(List<CarparamInVO> carParamInVos) {
        Map<String, List<CarparamInVO>> carParamInVoMap = new LinkedHashMap<>();
        List<String> disPlacementS = new ArrayList<>();
        for (CarparamInVO carparamInVO : carParamInVos) {
            if (!disPlacementS.contains(carparamInVO.getDisPlacement())) {
                disPlacementS.add(carparamInVO.getDisPlacement());
            }
        }
        for (String disPlacement : disPlacementS) {
            List<CarparamInVO> carParamInVoList = new ArrayList<>();
            for (CarparamInVO carparamInVO : carParamInVos) {
                if (disPlacement != null) {
                    logger.debug("-----:{}", disPlacement.equals(carparamInVO.getDisPlacement()));
                    if (disPlacement.equals(carparamInVO.getDisPlacement())) {
                        carParamInVoList.add(carparamInVO);
                    }
                }
            }
            carParamInVoMap.put(disPlacement, carParamInVoList);
        }
        List<GroupCarparamInVO> carParamInVOList = new ArrayList<>();
        for (Map.Entry<String, List<CarparamInVO>> entry : carParamInVoMap.entrySet()) {
            GroupCarparamInVO groupCarParamInVO = new GroupCarparamInVO();
            groupCarParamInVO.setName(entry.getKey());
            groupCarParamInVO.setList(entry.getValue());
            carParamInVOList.add(groupCarParamInVO);
        }
        return carParamInVOList;
    }

    /**
     * 查询整车产品信息
     *
     * @param page
     * @param queryParam
     * @return com.baomidou.mybatisplus.core.metadata.IPage<com.yonyou.cyxdms.basedata.service.vo.productinfo.VsProductVO>
     * @author renwd
     * @since 2019/7/17
     */
    @Override
    public IPage<VsProductVO> queryProductInfo(Page page, Map<String, Object> queryParam) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        MapUtils.addParameter(queryParam, loginInfoDto.getOwnerCode(), loginInfoDto.getAppId(), loginInfoDto.getGroupCode());
        queryParam.put("orgType", loginInfoDto.getOrgType());
        Object modelId = queryParam.get("modelId");
        logger.debug("参数参数参数modelId:{}", modelId);
        Object packageId = queryParam.get("packageId");
        logger.debug("参数参数参数packageId:{}", packageId);
        if (modelId != null && !"".equals(String.valueOf(modelId)) && "0".equals(String.valueOf(modelId))) {
            queryParam.put("modelId", null);
        }
        if (packageId != null && !"".equals(String.valueOf(packageId)) && "0".equals(String.valueOf(packageId))) {
            queryParam.put("packageId", null);
        }
        page.setRecords(vsProductMapper.queryProductInfo(page, queryParam));
        return page;
    }

    /**
     * 查询整车产品信息
     *
     * @param page
     * @param queryParam
     * @return com.baomidou.mybatisplus.core.metadata.IPage<com.yonyou.cyxdms.basedata.service.vo.productinfo.VsProductVO>
     * @author zys
     * @since 2020/2/12
     */
    @Override
    public IPage<VsProductVO> queryProductInfoV2(Page page, Map<String, Object> queryParam) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        MapUtils.addParameter(queryParam, loginInfoDto.getOwnerCode(), loginInfoDto.getAppId(), loginInfoDto.getGroupCode());
        queryParam.put("orgType", loginInfoDto.getOrgType());
        Object modelId = queryParam.get("modelId");
        logger.debug("参数参数参数modelId:{}", modelId);
        Object packageId = queryParam.get("packageId");
        logger.debug("参数参数参数packageId:{}", packageId);
        if (modelId != null && !"".equals(String.valueOf(modelId)) && "0".equals(String.valueOf(modelId))) {
            queryParam.put("modelId", null);
        }
        if (packageId != null && !"".equals(String.valueOf(packageId)) && "0".equals(String.valueOf(packageId))) {
            queryParam.put("packageId", null);
        }
        page.setRecords(vsProductMapper.queryProductInfoV2(page, queryParam));
        return page;
    }

    /**
     * 查询整车产品信息
     *
     * @param page
     * @param queryParam
     * @return com.baomidou.mybatisplus.core.metadata.IPage<com.yonyou.cyxdms.basedata.service.vo.productinfo.VsProductVO>
     * @author renwd
     * @since 2019/7/17
     */
    @Override
    public IPage<DcsVsProductVO> queryDcsProductInfo(Page page, Map<String, Object> queryParam) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        MapUtils.addParameter(queryParam, loginInfoDto.getOwnerCode(), loginInfoDto.getAppId(), loginInfoDto.getGroupCode());
        queryParam.put("orgType", loginInfoDto.getOrgType());
        Object modelId = queryParam.get("modelId");
        Object packageId = queryParam.get("packageId");
        if (modelId != null && !"".equals(String.valueOf(modelId)) && "0".equals(String.valueOf(modelId))) {
            queryParam.put("modelId", null);
        }
        if (packageId != null && !"".equals(String.valueOf(packageId)) && "0".equals(String.valueOf(packageId))) {
            queryParam.put("packageId", null);
        }
        page.setRecords(vsProductMapper.queryDcsProductInfo(page, queryParam));
        return page;
    }

    /**
     * 查询整车产品信息
     *
     * @param page
     * @param queryParam
     * @return com.baomidou.mybatisplus.core.metadata.IPage<com.yonyou.cyxdms.basedata.service.vo.productinfo.VsProductVO>
     * @author zys
     * @since 2020/2/11
     */
    @Override
    public IPage<DcsVsProductVO> queryDcsProductInfoV2(Page page, Map<String, Object> queryParam) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        MapUtils.addParameter(queryParam, loginInfoDto.getOwnerCode(), loginInfoDto.getAppId(), loginInfoDto.getGroupCode());
        queryParam.put("orgType", loginInfoDto.getOrgType());
        Object modelId = queryParam.get("modelId");
        Object packageId = queryParam.get("packageId");
        if (modelId != null && !"".equals(String.valueOf(modelId)) && "0".equals(String.valueOf(modelId))) {
            queryParam.put("modelId", null);
        }
        if (packageId != null && !"".equals(String.valueOf(packageId)) && "0".equals(String.valueOf(packageId))) {
            queryParam.put("packageId", null);
        }
        page.setRecords(vsProductMapper.queryDcsProductInfoV2(page, queryParam));
        return page;
    }

    /**
     * 导出
     *
     * @param queryParam
     * @return void
     * @author renwd
     * @since 2019/7/18
     */
    @Override
    public void exportProductInfos(Map<String, Object> queryParam, HttpServletRequest request, HttpServletResponse response) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        MapUtils.addParameter(queryParam, loginInfoDto.getOwnerCode(), loginInfoDto.getAppId(), loginInfoDto.getGroupCode());
        queryParam.put("orgType", loginInfoDto.getOrgType());
        List<Map> resultList = vsProductMapper.queryProductInfoForExport(queryParam);
        Map<String, List<Map>> excelData = new HashMap<>();
        excelData.put("整车产品信息", resultList);
        List<ExcelExportColumn> exportColumnList = new ArrayList<>();
        exportColumnList.add(new ExcelExportColumn("PRODUCT_CODE", "产品代码"));
        exportColumnList.add(new ExcelExportColumn("PRODUCT_NAME", "产品名称"));
        exportColumnList.add(new ExcelExportColumn("BRAND_NAME", "品牌"));
        exportColumnList.add(new ExcelExportColumn("SERIES_NAME", "车系"));
        exportColumnList.add(new ExcelExportColumn("MODEL_NAME", "车型"));
        exportColumnList.add(new ExcelExportColumn("PACKAGE_NAME", "配置"));
        exportColumnList.add(new ExcelExportColumn("COLOR", "外饰色"));
        exportColumnList.add(new ExcelExportColumn("TRIM_COLOR", "内饰色"));
        exportColumnList.add(new ExcelExportColumn("DATA_SOURCES", "数据来源", ExcelDataType.Dict));
        exportColumnList.add(new ExcelExportColumn("VEHICLE_SOURCES", "车辆来源", ExcelDataType.Dict));
        //其它类型：Region_Provice,Region_City,Region_Country
        exportColumnList.add(new ExcelExportColumn("IS_VALID", "是否有效", ExcelDataType.Dict));
        exportColumnList.add(new ExcelExportColumn("PRODUCT_STATUS", "产品状态", ExcelDataType.Dict));
        exportColumnList.add(new ExcelExportColumn("PRODUCT_TYPE", "产品类别", ExcelDataType.Dict));
        exportColumnList.add(new ExcelExportColumn("OEM_DIRECTIVE_PRICE", "车厂指导价"));
        exportColumnList.add(new ExcelExportColumn("VEHICLE_PRICE", "销售指导价"));
        exportColumnList.add(new ExcelExportColumn("ENTER_DATE", "上市日期"));
        exportColumnList.add(new ExcelExportColumn("EXEUNT_DATE", "退市日期"));
        exportColumnList.add(new ExcelExportColumn("REMARK", "备注"));
        excelService.generateExcel(excelData, exportColumnList, "整车产品信息.xls", request, response);
    }

    /**
     * 导出
     *
     * @param queryParam
     * @return void
     * @author zys
     * @since 2020/2/11
     */
    @Override
    public void exportProductInfosV2(Map<String, Object> queryParam, HttpServletRequest request, HttpServletResponse response) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        MapUtils.addParameter(queryParam, loginInfoDto.getOwnerCode(), loginInfoDto.getAppId(), loginInfoDto.getGroupCode());
        queryParam.put("orgType", loginInfoDto.getOrgType());
        List<Map> resultList = vsProductMapper.queryProductInfoForExportV2(queryParam);
        Map<String, List<Map>> excelData = new HashMap<>();
        excelData.put("整车产品信息", resultList);
        List<ExcelExportColumn> exportColumnList = new ArrayList<>();
        exportColumnList.add(new ExcelExportColumn("PRODUCT_CODE", "产品代码"));
        exportColumnList.add(new ExcelExportColumn("PRODUCT_NAME", "产品名称"));
        exportColumnList.add(new ExcelExportColumn("BRAND_NAME", "品牌"));
        exportColumnList.add(new ExcelExportColumn("SERIES_NAME", "车系"));
        exportColumnList.add(new ExcelExportColumn("MODEL_NAME", "车型"));
        exportColumnList.add(new ExcelExportColumn("PACKAGE_NAME", "配置"));
        exportColumnList.add(new ExcelExportColumn("OPTION_NAME", "选装"));
        exportColumnList.add(new ExcelExportColumn("COLOR", "外饰色"));
        exportColumnList.add(new ExcelExportColumn("TRIM_COLOR", "内饰色"));
        exportColumnList.add(new ExcelExportColumn("DATA_SOURCES", "数据来源", ExcelDataType.Dict));
        exportColumnList.add(new ExcelExportColumn("VEHICLE_SOURCES", "车辆来源", ExcelDataType.Dict));
        //其它类型：Region_Provice,Region_City,Region_Country
        exportColumnList.add(new ExcelExportColumn("IS_VALID", "是否有效", ExcelDataType.Dict));
        exportColumnList.add(new ExcelExportColumn("PRODUCT_STATUS", "产品状态", ExcelDataType.Dict));
        exportColumnList.add(new ExcelExportColumn("PRODUCT_TYPE", "产品类别", ExcelDataType.Dict));
        exportColumnList.add(new ExcelExportColumn("OEM_DIRECTIVE_PRICE", "车厂指导价"));
        exportColumnList.add(new ExcelExportColumn("VEHICLE_PRICE", "销售指导价"));
        exportColumnList.add(new ExcelExportColumn("ENTER_DATE", "上市日期"));
        exportColumnList.add(new ExcelExportColumn("EXEUNT_DATE", "退市日期"));
        exportColumnList.add(new ExcelExportColumn("REMARK", "备注"));
        excelService.generateExcel(excelData, exportColumnList, "整车产品信息.xls", request, response);
    }

    /**
     * 根据id查询主数据
     *
     * @param id
     * @return com.yonyou.cyxdms.basedata.service.vo.productinfo.VsMasterInfoVO
     * @author renwd
     * @since 2019/7/24
     */
    @Override
    public VsMasterInfoVO queryProductInfoById(Long id) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        Map<String, Object> queryParam = new HashMap<>();
        queryParam.put("productId", id);
        queryParam.put("appId", loginInfoDto.getAppId());
        queryParam.put("ownerCode", loginInfoDto.getOwnerCode());
        return vsProductMapper.queryProductInfoById(queryParam);
    }

    /**
     * TCC获取车辆主数据
     *
     * @param id
     * @return
     * @author ysj
     * @date 2019/11/19
     */
    @Override
    public VsMasterInfoVO queryTccProductInfoById(Long id) {
        Map<String, Object> queryParam = new HashMap<>();
        queryParam.put("productId", id);
        return vsProductMapper.queryTccProductInfoById(queryParam);
    }

    /**
     * 修改车辆主数据
     *
     * @param id
     * @param vehicleMasterInfoDto
     * @return void
     * @author renwd
     * @since 2019/7/24
     */
    @Override
    public void modifyProductInfo(Long id, VehicleMasterInfoDTO vehicleMasterInfoDto) {
        VsProductPO vsProductPo = vsProductMapper.selectById(id);
        PackagePO packagePo = packageMapper.selectById(vehicleMasterInfoDto.getPackageId());
        ModelPO modelPo = modelMapper.selectById(packagePo.getModelId());
        SeriesPO seriesPo = seriesMapper.selectById(modelPo.getSeriesId());
        vsProductPo.setProductCode(vehicleMasterInfoDto.getProductCode());
        vsProductPo.setProductName(vehicleMasterInfoDto.getProductName());
        vsProductPo.setPackageId(packagePo.getPackageId());
        vsProductPo.setModelId(modelPo.getModelId());
        vsProductPo.setSeriesId(seriesPo.getSeriesId());
        vsProductPo.setBrandId(seriesPo.getBrandId());
        vsProductPo.setDataSources(BasedataDictConstants.DATA_SOURCES_BY_GROUP);
        vsProductPo.setColorId(vehicleMasterInfoDto.getColor());
        vsProductPo.setTrimColor(vehicleMasterInfoDto.getTrimColor());
        vsProductPo.setIsPurchase(vehicleMasterInfoDto.getIsPurchase());
        vsProductPo.setIsSales(vehicleMasterInfoDto.getIsSales());
        vsProductPo.setIsValid(vehicleMasterInfoDto.getIsValid());
        vsProductPo.setOemDirectivePrice(vehicleMasterInfoDto.getOemDirectivePrice());
        vsProductPo.setEnterDate(vehicleMasterInfoDto.getEnterDate());
        vsProductPo.setExeuntDate(vehicleMasterInfoDto.getExeuntDate());
        vsProductPo.setVehicleSources(vehicleMasterInfoDto.getVehicleSources());
        vsProductPo.setRemark(vehicleMasterInfoDto.getRemark());
        vsProductMapper.updateById(vsProductPo);
    }

    /**
     * 获取车型配置树
     *
     * @param productTreeDTO
     * @return
     * @author ysj
     * @date 2019/09/10
     */
    @Override
    public List<BrandTreeVO> getProductTree(ProductTreeDTO productTreeDTO) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        //判断缓存中是否有产品列表
        String messageFormat = MessageFormat.format(BaseDataCommonConstants.PRODUCT_CACHE_DATA, loginInfoDto.getAppId(), productTreeDTO.getType(), productTreeDTO.getLevel());
        Object productDto = redisClient.hget(messageFormat, String.valueOf(productTreeDTO.getIsUnlimited()));
        if (null != productDto) {
            logger.info("读取缓存中的产品列表:--------------------------");
            return JSONUtil.jsonToList(JSONUtil.objectToJson(productDto), BrandTreeVO.class);
        }
        //获取所有数据(到颜色那一级的所有数据)
        List<ProductDataVO> dataList = vsProductMapper.getProductData(loginInfoDto.getAppId(), loginInfoDto.getGroupCode(), loginInfoDto.getOwnerCode());
        String brandId = "";
        String seriesId = "";
        String modelId = "";
        String packageId = "";
        List<ColorTreeVO> colorChildren = new ArrayList<>();
        List<PackageTreeVO> packageChildren = new ArrayList<>();
        List<ModelTreeVO> modelChildren = new ArrayList<>();
        List<SeriesTreeVO> seriesChildren = new ArrayList<>();
        List<BrandTreeVO> brandList = new ArrayList<>();
        for (int i = 0, j = dataList.size(); i < j; i++) {
            ProductDataVO productDataVO = dataList.get(i);
            if (productDataVO == null) {
                continue;
            }

            //设置第一级--品牌
            if (!brandId.equals(productDataVO.getBrandId()) && productTreeDTO.getLevel() >= 1) {
                seriesChildren = new ArrayList<>();
                setBrand(productDataVO, productTreeDTO.getType(), seriesChildren, brandList);
                brandId = productDataVO.getBrandId() == null ? "" : productDataVO.getBrandId();
            }

            //设置第二级--车系
            if (!seriesId.equals(productDataVO.getSeriesId()) && productTreeDTO.getLevel() >= 2) {
                modelChildren = new ArrayList<>();
                setSeries(productDataVO, productTreeDTO.getType(), modelChildren, seriesChildren,
                        productTreeDTO.getIsUnlimited(), productTreeDTO.getLevel());
                seriesId = productDataVO.getSeriesId() == null ? "" : productDataVO.getSeriesId();
            }

            //设置第三级--车型
            if (!modelId.equals(productDataVO.getModelId()) && productTreeDTO.getLevel() >= 3) {
                packageChildren = new ArrayList<>();
                setModel(productDataVO, productTreeDTO.getType(), packageChildren, modelChildren,
                        productTreeDTO.getIsUnlimited(), productTreeDTO.getLevel());
                modelId = productDataVO.getModelId() == null ? "" : productDataVO.getModelId();
            }

            //设置第四级--配置
            if (!packageId.equals(productDataVO.getPackageId()) && productTreeDTO.getLevel() >= 4) {
                colorChildren = new ArrayList<>();
                setPackage(productDataVO, productTreeDTO.getType(), colorChildren, packageChildren,
                        productTreeDTO.getIsUnlimited(), productTreeDTO.getLevel());
                packageId = productDataVO.getPackageId() == null ? "" : productDataVO.getPackageId();
            }

            //设置第五级--颜色
            if (productTreeDTO.getLevel() >= 5) {
                setColor(productDataVO, productTreeDTO.getType(), colorChildren);
            }
        }
        cacheProduct(brandList, messageFormat, String.valueOf(productTreeDTO.getIsUnlimited()));
        return brandList;

    }

    /**
     * 获取车型配置树
     * 增加选装层级
     *
     * @param productTreeDTO
     * @return
     * @author zy
     * @date 2020/02/20
     */
    @Override
    public List<BrandTreeNewVO> getProductTreeNew(ProductTreeDTO productTreeDTO) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        //判断缓存中是否有产品列表
        String messageFormat = MessageFormat.format(BaseDataCommonConstants.PRODUCT_CACHE_DATA, loginInfoDto.getAppId(), productTreeDTO.getType(), productTreeDTO.getLevel());
        Object productDto = redisClient.hget(messageFormat, String.valueOf(productTreeDTO.getIsUnlimited()));
        if (null != productDto) {
            logger.info("读取缓存中的产品列表:--------------------------");
            return JSONUtil.jsonToList(JSONUtil.objectToJson(productDto), BrandTreeNewVO.class);
        }
        //获取所有数据(到颜色那一级的所有数据)
        List<ProductDataVO> dataList = vsProductMapper.getProductDataNew(loginInfoDto.getAppId(), loginInfoDto.getGroupCode(), loginInfoDto.getOwnerCode());
        String brandId = "";
        String seriesId = "";
        String modelId = "";
        String packageId = "";
        String optionId = "";
        List<OptionTreeVO> optionChildren = new ArrayList<>();
        List<ColorTreeVO> colorChildren = new ArrayList<>();
        List<PackageTreeNewVO> packageChildren = new ArrayList<>();
        List<ModelTreeNewVO> modelChildren = new ArrayList<>();
        List<SeriesTreeNewVO> seriesChildren = new ArrayList<>();
        List<BrandTreeNewVO> brandList = new ArrayList<>();
        for (int i = 0, j = dataList.size(); i < j; i++) {
            ProductDataVO productDataVO = dataList.get(i);
            if (productDataVO == null) {
                continue;
            }

            //设置第一级--品牌
            if (!brandId.equals(productDataVO.getBrandId()) && productTreeDTO.getLevel() >= 1) {
                seriesChildren = new ArrayList<>();
                setBrandNew(productDataVO, productTreeDTO.getType(), seriesChildren, brandList,
                        productTreeDTO.getIsUnlimited(), productTreeDTO.getLevel());
                brandId = productDataVO.getBrandId() == null ? "" : productDataVO.getBrandId();
            }

            //设置第二级--车系
            if (!seriesId.equals(productDataVO.getSeriesId()) && productTreeDTO.getLevel() >= 2) {
                modelChildren = new ArrayList<>();
                setSeriesNew(productDataVO, productTreeDTO.getType(), modelChildren, seriesChildren,
                        productTreeDTO.getIsUnlimited(), productTreeDTO.getLevel());
                seriesId = productDataVO.getSeriesId() == null ? "" : productDataVO.getSeriesId();
            }

            //设置第三级--车型
            if (!modelId.equals(productDataVO.getModelId()) && productTreeDTO.getLevel() >= 3) {
                packageChildren = new ArrayList<>();
                setModelNew(productDataVO, productTreeDTO.getType(), packageChildren, modelChildren,
                        productTreeDTO.getIsUnlimited(), productTreeDTO.getLevel());
                modelId = productDataVO.getModelId() == null ? "" : productDataVO.getModelId();
            }

            //设置第四级--配置
            if (!packageId.equals(productDataVO.getPackageId()) && productTreeDTO.getLevel() >= 4) {
                optionChildren = new ArrayList<>();
                setPackageNew(productDataVO, productTreeDTO.getType(), optionChildren, packageChildren,
                        productTreeDTO.getIsUnlimited(), productTreeDTO.getLevel());
                packageId = productDataVO.getPackageId() == null ? "" : productDataVO.getPackageId();
            }

            //设置第五级--选装
            if ( productTreeDTO.getLevel() >= 5) {
                colorChildren = new ArrayList<>();
                setOption(productDataVO, productTreeDTO.getType(), colorChildren, optionChildren,
                        productTreeDTO.getIsUnlimited(), productTreeDTO.getLevel());
                optionId = productDataVO.getOptionId() == null ? "" : productDataVO.getOptionId();
            }

            //设置第五级--颜色
            if (productTreeDTO.getLevel() >= 6) {
                setColor(productDataVO, productTreeDTO.getType(), colorChildren);
            }
        }
        cacheProductNew(brandList, messageFormat, String.valueOf(productTreeDTO.getIsUnlimited()));
        return brandList;

    }

    /**
     * 查询产品配置名称
     *
     * @param vehicleInfoDTO
     * @return
     */
    @Override
    public VehicleInfoVO getVehicleInfoByName(VehicleInfoDTO vehicleInfoDTO) {
        return vsProductMapper.getVehicleInfoByName(vehicleInfoDTO.toMaps());
    }

    /**
     * 通过产品代码查出productIds
     *
     * @param productCode
     * @return java.util.List<java.lang.Long>
     * @author dengqiang
     * @since 2019/10/22
     */
    @Override
    public List<Long> queryProductIdsBy(String productCode) {
        LambdaQueryWrapper<VsProductPO> param = new QueryWrapper<VsProductPO>().lambda();
        param.like(VsProductPO::getProductCode, productCode);
        List<VsProductPO> vsProductPos = vsProductMapper.selectList(param);
        List<Long> productIds = new ArrayList<>();
        for (VsProductPO vsProductPo : vsProductPos) {
            productIds.add(vsProductPo.getProductId());
        }
        return productIds;
    }

    /**
     * 查询整车产品信息
     *
     * @param page
     * @param queryParam
     * @return com.baomidou.mybatisplus.core.metadata.IPage<com.yonyou.cyxdms.basedata.service.vo.productinfo.VsProductVO>
     * @author renwd
     * @since 2019/7/19
     */
    @Override
    public IPage<VsProductVO> queryVehicleMasterInfo(Page page, Map<String, Object> queryParam) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        MapUtils.addParameter(queryParam, loginInfoDto.getOwnerCode(), loginInfoDto.getAppId(), loginInfoDto.getGroupCode());
        page.setRecords(vsProductMapper.vehicleMasterInfo(page, queryParam));
        return page;
    }

    /**
     * 保存产品数据到redis
     *
     * @param treeCache
     * @param key
     * @param type
     * @author ysj
     * @date 2019/09/12
     */
    private void cacheProduct(List<BrandTreeVO> treeCache, String key, String type) {
        redisClient.hsetExpire(key, type, JSONUtil.objectToJson(treeCache),
                BaseDataCommonConstants.EXPIRE_TIME_ONE_DAY);
    }

    /**
     * 保存产品数据到redis
     *
     * @param treeCache
     * @param key
     * @param type
     * @author zy
     * @date 2020/02/10
     */
    private void cacheProductNew(List<BrandTreeNewVO> treeCache, String key, String type) {
        redisClient.hsetExpire(key, type, JSONUtil.objectToJson(treeCache),
                BaseDataCommonConstants.EXPIRE_TIME_ONE_DAY);
    }

    /**
     * 产品树设置品牌
     *
     * @param productDataVO  产品数据
     * @param type           返回value类型 0:id 1:code
     * @param seriesChildren 品牌下一级车系
     * @param brandList      品牌列表
     * @author ysj
     * @date 2019/09/12
     */
    private void setBrand(ProductDataVO productDataVO, Integer type,
                          List<SeriesTreeVO> seriesChildren, List<BrandTreeVO> brandList) {
        BrandTreeVO brandTreeVO = new BrandTreeVO();
        brandTreeVO.setText(productDataVO.getBrandName());
        brandTreeVO.setValue(type == 0 ? productDataVO.getBrandId() : productDataVO.getBrandCode());
        brandTreeVO.setChildren(seriesChildren);
        brandList.add(brandTreeVO);
    }

    /**
     * 产品树设置品牌
     *
     * @param productDataVO  产品数据
     * @param type           返回value类型 0:id 1:code
     * @param seriesChildren 品牌下一级车系
     * @param brandList      品牌列表
     * @author zy
     * @date 2020/02/10
     */
    private void setBrandNew(ProductDataVO productDataVO, Integer type,
                             List<SeriesTreeNewVO> seriesChildren, List<BrandTreeNewVO> brandList, Integer isUnlimited, Integer level) {
        //是否添加不限
        if (BasedataDictConstants.IS_VALID == isUnlimited && level >= BasedataCommonConstants.PRODUCT_TREE_THREE) {
            SeriesTreeNewVO seriesTreeVO = new SeriesTreeNewVO();
            seriesTreeVO.setText(BasedataCommonConstants.PRODUCT_TYPE);
            seriesTreeVO.setValue(BasedataCommonConstants.ZERO);
            seriesChildren.add(seriesTreeVO);
        }
        //如果层级不到当前层级的下一级,下一级设置为null
        if (level < BasedataCommonConstants.PRODUCT_TREE_TWO) {
            seriesChildren = null;
        }
        BrandTreeNewVO brandTreeVO = new BrandTreeNewVO();
        brandTreeVO.setText(productDataVO.getBrandName());
        brandTreeVO.setValue(type == 0 ? productDataVO.getBrandId() : productDataVO.getBrandCode());
        brandTreeVO.setChildren(seriesChildren);
        brandList.add(brandTreeVO);
    }

    /**
     * 产品树设置车系
     *
     * @param productDataVO  产品数据
     * @param type           返回value类型 0:id 1:code
     * @param modelChildren  车系下一级车型
     * @param seriesChildren 车系列表
     * @param isUnlimited    是否有不限
     * @author ysj
     * @date 2019/09/12
     */
    private void setSeries(ProductDataVO productDataVO, Integer type,
                           List<ModelTreeVO> modelChildren, List<SeriesTreeVO> seriesChildren,
                           Integer isUnlimited, Integer level) {
        //是否添加不限
        if (BasedataDictConstants.IS_VALID == isUnlimited && level >= BasedataCommonConstants.PRODUCT_TREE_THREE) {
            ModelTreeVO modelTreeVO = new ModelTreeVO();
            modelTreeVO.setText(BasedataCommonConstants.PRODUCT_TYPE);
            modelTreeVO.setValue(BasedataCommonConstants.ZERO);
            modelChildren.add(modelTreeVO);
        }

        //如果层级不到当前层级的下一级,下一级设置为null
        if (level < BasedataCommonConstants.PRODUCT_TREE_THREE) {
            modelChildren = null;
        }

        SeriesTreeVO seriesTreeVO = new SeriesTreeVO();
        seriesTreeVO.setText(productDataVO.getSeriesName());
        seriesTreeVO.setValue(type == 0 ? productDataVO.getSeriesId() : productDataVO.getSeriesCode());
        seriesTreeVO.setChildren(modelChildren);
        seriesChildren.add(seriesTreeVO);
    }

    /**
     * 产品树设置车系
     *
     * @param productDataVO  产品数据
     * @param type           返回value类型 0:id 1:code
     * @param modelChildren  车系下一级车型
     * @param seriesChildren 车系列表
     * @param isUnlimited    是否有不限
     * @author ysj
     * @date 2019/09/12
     */
    private void setSeriesNew(ProductDataVO productDataVO, Integer type,
                              List<ModelTreeNewVO> modelChildren, List<SeriesTreeNewVO> seriesChildren,
                              Integer isUnlimited, Integer level) {
        //是否添加不限
        if (BasedataDictConstants.IS_VALID == isUnlimited && level >= BasedataCommonConstants.PRODUCT_TREE_THREE) {
            ModelTreeNewVO modelTreeVO = new ModelTreeNewVO();
            modelTreeVO.setText(BasedataCommonConstants.PRODUCT_TYPE);
            modelTreeVO.setValue(BasedataCommonConstants.ZERO);
            modelChildren.add(modelTreeVO);
        }

        //如果层级不到当前层级的下一级,下一级设置为null
        if (level < BasedataCommonConstants.PRODUCT_TREE_THREE) {
            modelChildren = null;
        }

        SeriesTreeNewVO seriesTreeVO = new SeriesTreeNewVO();
        seriesTreeVO.setText(productDataVO.getSeriesName());
        seriesTreeVO.setValue(type == 0 ? productDataVO.getSeriesId() : productDataVO.getSeriesCode());
        seriesTreeVO.setChildren(modelChildren);
        seriesChildren.add(seriesTreeVO);
    }

    /**
     * 产品树配置车型
     *
     * @param productDataVO   产品数据
     * @param type            返回value类型 0:id 1:code
     * @param packageChildren 车型下一级配置
     * @param modelChildren   车型列表
     * @param isUnlimited     是否有不限
     * @author ysj
     * @date 2019/09/12
     */
    private void setModel(ProductDataVO productDataVO, Integer type,
                          List<PackageTreeVO> packageChildren, List<ModelTreeVO> modelChildren,
                          Integer isUnlimited, Integer level) {
        //是否添加不限
        if (BasedataDictConstants.IS_VALID == isUnlimited && level >= BasedataCommonConstants.PRODUCT_TREE_FURE) {
            PackageTreeVO packageTreeVO = new PackageTreeVO();
            packageTreeVO.setText(BasedataCommonConstants.PRODUCT_TYPE);
            packageTreeVO.setValue(BasedataCommonConstants.ZERO);
            packageChildren.add(packageTreeVO);
        }

        //如果层级不到当前层级的下一级,下一级设置为null
        if (level < BasedataCommonConstants.PRODUCT_TREE_FURE) {
            packageChildren = null;
        }

        ModelTreeVO modelTreeVO = new ModelTreeVO();
        modelTreeVO.setText(productDataVO.getModelName());
        modelTreeVO.setValue(type == 0 ? productDataVO.getModelId() : productDataVO.getModelCode());
        modelTreeVO.setChildren(packageChildren);
        modelChildren.add(modelTreeVO);
    }

    /**
     * 产品树配置车型
     *
     * @param productDataVO   产品数据
     * @param type            返回value类型 0:id 1:code
     * @param packageChildren 车型下一级配置
     * @param modelChildren   车型列表
     * @param isUnlimited     是否有不限
     * @author ysj
     * @date 2019/09/12
     */
    private void setModelNew(ProductDataVO productDataVO, Integer type,
                             List<PackageTreeNewVO> packageChildren, List<ModelTreeNewVO> modelChildren,
                             Integer isUnlimited, Integer level) {
        //是否添加不限
        if (BasedataDictConstants.IS_VALID == isUnlimited && level >= BasedataCommonConstants.PRODUCT_TREE_FURE) {
            PackageTreeNewVO packageTreeVO = new PackageTreeNewVO();
            packageTreeVO.setText(BasedataCommonConstants.PRODUCT_TYPE);
            packageTreeVO.setValue(BasedataCommonConstants.ZERO);
            packageChildren.add(packageTreeVO);
        }

        //如果层级不到当前层级的下一级,下一级设置为null
        if (level < BasedataCommonConstants.PRODUCT_TREE_FURE) {
            packageChildren = null;
        }

        ModelTreeNewVO modelTreeVO = new ModelTreeNewVO();
        modelTreeVO.setText(productDataVO.getModelName());
        modelTreeVO.setValue(type == 0 ? productDataVO.getModelId() : productDataVO.getModelCode());
        modelTreeVO.setChildren(packageChildren);
        modelChildren.add(modelTreeVO);
    }

    /**
     * 产品树设置配置
     *
     * @param productDataVO   产品数据
     * @param type            返回value类型 0:id 1:code
     * @param colorChildren   车型下一级配置
     * @param packageChildren 车型列表
     * @param isUnlimited     是否有不限
     * @author ysj
     * @date 2019/09/12
     */
    private void setPackage(ProductDataVO productDataVO, Integer type,
                            List<ColorTreeVO> colorChildren, List<PackageTreeVO> packageChildren,
                            Integer isUnlimited, Integer level) {
        //是否添加不限
        if (BasedataDictConstants.IS_VALID == isUnlimited && level >= BasedataCommonConstants.PRODUCT_TREE_FIVE) {
            ColorTreeVO colorTreeVO = new ColorTreeVO();
            colorTreeVO.setText(BasedataCommonConstants.PRODUCT_TYPE);
            colorTreeVO.setValue(BasedataCommonConstants.ZERO);
            colorChildren.add(colorTreeVO);
        }

        //如果层级不到当前层级的下一级,下一级设置为null
        if (level < BasedataCommonConstants.PRODUCT_TREE_FIVE) {
            colorChildren = null;
        }

        PackageTreeVO packageTreeVO = new PackageTreeVO();
        packageTreeVO.setText(productDataVO.getConfigName());
        packageTreeVO.setValue(type == 0 ? productDataVO.getPackageId() : productDataVO.getConfigCode());
        packageTreeVO.setChildren(colorChildren);
        packageChildren.add(packageTreeVO);
    }

    /**
     * 产品树设置配置
     *
     * @param productDataVO   产品数据
     * @param type            返回value类型 0:id 1:code
     * @param optionChildren  车型下一级配置
     * @param packageChildren 车型列表
     * @param isUnlimited     是否有不限
     * @author zy
     * @date 2020/02/10
     */
    private void setPackageNew(ProductDataVO productDataVO, Integer type,
                               List<OptionTreeVO> optionChildren, List<PackageTreeNewVO> packageChildren,
                               Integer isUnlimited, Integer level) {
        //是否添加不限
        if (BasedataDictConstants.IS_VALID == isUnlimited && level >= BasedataCommonConstants.PRODUCT_TREE_FIVE) {
            OptionTreeVO optionTree = new OptionTreeVO();
            optionTree.setText(BasedataCommonConstants.PRODUCT_TYPE);
            optionTree.setValue(BasedataCommonConstants.ZERO);
            optionChildren.add(optionTree);
        }

        //如果层级不到当前层级的下一级,下一级设置为null
        if (level < BasedataCommonConstants.PRODUCT_TREE_FIVE) {
            optionChildren = null;
        }

        PackageTreeNewVO packageTreeVO = new PackageTreeNewVO();
        packageTreeVO.setText(productDataVO.getConfigName());
        packageTreeVO.setValue(type == 0 ? productDataVO.getPackageId() : productDataVO.getConfigCode());
        packageTreeVO.setChildren(optionChildren);
        packageChildren.add(packageTreeVO);
    }

    /**
     * 产品树设置配置
     *
     * @param productDataVO 产品数据
     * @param type          返回value类型 0:id 1:code
     * @param colorChildren 车型下一级配置
     * @param isUnlimited   是否有不限
     * @author zy
     * @date 2020/02/10
     */
    private void setOption(ProductDataVO productDataVO, Integer type,
                           List<ColorTreeVO> colorChildren, List<OptionTreeVO> optionChildren,
                           Integer isUnlimited, Integer level) {
        //是否添加不限
        if (BasedataDictConstants.IS_VALID == isUnlimited && level >= BasedataCommonConstants.PRODUCT_TREE_SIX) {
            ColorTreeVO colorTreeVO = new ColorTreeVO();
            colorTreeVO.setText(BasedataCommonConstants.PRODUCT_TYPE);
            colorTreeVO.setValue(BasedataCommonConstants.ZERO);
            colorChildren.add(colorTreeVO);
        }

        //如果层级不到当前层级的下一级,下一级设置为null
        if (level < BasedataCommonConstants.PRODUCT_TREE_SIX) {
            colorChildren = null;
        }

        OptionTreeVO optionTreeVO = new OptionTreeVO();
        optionTreeVO.setText(productDataVO.getOptionName());
        optionTreeVO.setValue(type == 0 ? productDataVO.getOptionId() : productDataVO.getOptionCode());
        optionTreeVO.setChildren(colorChildren);
        optionChildren.add(optionTreeVO);
    }

    /**
     * 产品树配置颜色
     *
     * @param productDataVO 产品数据
     * @param type          返回value类型 0:id 1:code
     * @param colorChildren 颜色列表
     * @author ysj
     * @date 2019/09/12
     */
    private void setColor(ProductDataVO productDataVO, Integer type, List<ColorTreeVO> colorChildren) {
        ColorTreeVO colorTreeVO = new ColorTreeVO();
        List<String> ids = new ArrayList<>();
        if (null != colorChildren && colorChildren.size() > 0) {
            ids = colorChildren.stream().map(x -> x.getValue()).collect(Collectors.toList());
        }
        if ((ids != null && ids.size() > 0) && ids.contains(type == 0 ? productDataVO.getColorId() : productDataVO.getColorCode())) {

        } else {
            colorTreeVO.setText(productDataVO.getColorName());
            colorTreeVO.setValue(type == 0 ? productDataVO.getColorId() : productDataVO.getColorCode());
            colorTreeVO.setProductId(productDataVO.getProductId());
            colorChildren.add(colorTreeVO);
        }
    }

    /**
     * 产品树配置产品
     *
     * @param productDataVO 产品数据
     * @param type          返回value类型 0:id 1:code
     * @param colorChildren 颜色列表
     * @author zys
     * @date 2020/01/06
     */
    private void setColor1(ProductDataVO productDataVO, Integer type, List<ColorTreeVO> colorChildren) {
        ColorTreeVO colorTreeVO = new ColorTreeVO();
        colorTreeVO.setText(productDataVO.getProductName());
        colorTreeVO.setValue(type == 0 ? productDataVO.getColorId().toString() : productDataVO.getColorCode());
        colorTreeVO.setProductId(productDataVO.getProductId());
        colorChildren.add(colorTreeVO);
    }

    /**
     * 通用-新增/更新定义整车产品
     *
     * @author：chenzb
     * @since：2019-10-12
     */
    @Override
    public void addVsProductGeneral(List<GeneralVsProductDTO> generalVsProductDto) {
        logger.debug("厂端同步至后台的整车定义数据:{}", generalVsProductDto);
        if (CollectionUtils.isNotEmpty(generalVsProductDto)) {
            // 数据不为空遍历存储
            for (GeneralVsProductDTO generalVsProductDTO : generalVsProductDto) {
                QueryWrapper<VsProductPO> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda().eq(VsProductPO::getAppId, generalVsProductDTO.getAppId())
                        .eq(VsProductPO::getSourceId, generalVsProductDTO.getSourceId());
                VsProductPO oldVsProductPo = vsProductMapper.selectOne(queryWrapper);
                // colorCode 根据颜色Code获取颜色ID
                ColorPO colorPo = colorMapper.getByCode(generalVsProductDTO.getAppId(), generalVsProductDTO.getColorCode());
                // packageCode 根据packageCode获取配置信息-车型基础数据的ID
                VehicleProductPackageVO packagePo = packageMapper.getByPackId(generalVsProductDTO.getAppId(), generalVsProductDTO.getPackageCode());
                String ownerCode = StringUtils.isBlank(generalVsProductDTO.getOwnerCode()) ? "-1" : generalVsProductDTO.getOwnerCode();
                // ownerCode设值-1 标记车厂下发
                if (oldVsProductPo == null) {
                    // 新增整车定义
                    VsProductPO vsProductPo = BeanMapperUtil.copyProperties(generalVsProductDTO, VsProductPO.class);
                    //获取品牌
                    setParams(colorPo, packagePo, ownerCode, vsProductPo);
                    vsProductPo.setSourceChangedAt(LocalDateTime.now());
                    vsProductPo.setCreatedAt(LocalDateTime.now());
                    vsProductPo.setIsValid(10041001);
                    logger.debug("开始新增插入整车定义数据:{}", vsProductPo);
                    vsProductMapper.insert(vsProductPo);
                } else {
                    // 更新整车定义
                    VsProductPO vsProductPo = BeanMapperUtil.copyProperties(generalVsProductDTO, VsProductPO.class);
                    vsProductPo.setOwnerCode(ownerCode);
                    vsProductPo.setCompanyCode(ownerCode);
                    vsProductPo.setOwnerParCode(ownerCode);
                    setParams(colorPo, packagePo, ownerCode, vsProductPo);
                    vsProductPo.setProductId(oldVsProductPo.getProductId());
                    vsProductPo.setIsValid(generalVsProductDTO.getIsValid());
                    vsProductPo.setCreatedBy("-1");
                    vsProductPo.setRecordVersion(oldVsProductPo.getRecordVersion());
                    vsProductPo.setIsDeleted(generalVsProductDTO.getIsDelete() == null ? 0 : generalVsProductDTO.getIsDelete());
                    logger.debug("开始更新整车定义数据:{}", vsProductPo);
                    vsProductMapper.updateById(vsProductPo);
                }
            }
        } else {
            throw new ServiceBizException("厂端传来的整车定义数据的缺失！");
        }
    }

    /**
     * 更新-车辆主数据
     * 整车物料号价格维护
     *
     * @param vsProductPriceDTO
     * @author：chenzb
     * @since：2019-11-27
     */
    @Override
    public Integer updateProductInfo(VsProductPriceDTO vsProductPriceDTO) {
        logger.info("更新-车辆主数据，整车物料号价格维护！--参数vsProductPriceDTO:{}", vsProductPriceDTO);
        if (vsProductPriceDTO == null) {
            throw new ServiceBizException("参数为空，无法进行更新操作！");
        }
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        QueryWrapper<VsProductPricePO> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(VsProductPricePO::getAppId, loginInfoDto.getAppId())
                .eq(VsProductPricePO::getOwnerCode, loginInfoDto.getOwnerCode())
                .eq(VsProductPricePO::getProductId, vsProductPriceDTO.getProductId())
                .eq(VsProductPricePO::getIsDeleted, 0);
        VsProductPricePO oldVsProductPricePo = vsProductPriceMapper.selectOne(queryWrapper);
        if (oldVsProductPricePo == null) {
            VsProductPricePO vsProductPricePo = new VsProductPricePO();
            BeanUtil.copyProperties(vsProductPriceDTO, vsProductPricePo);
            vsProductPriceMapper.insert(vsProductPricePo);
        } else {
            BeanUtil.copyProperties(vsProductPriceDTO, oldVsProductPricePo);
            vsProductPriceMapper.updateById(oldVsProductPricePo);
        }
        return 1;
    }

    private void setParams(ColorPO colorPo, VehicleProductPackageVO packagePo, String ownerCode, VsProductPO vsProductPo) {
        vsProductPo.setColorId(Long.valueOf(colorPo.getColorId().toString()));
        vsProductPo.setBrandId(Long.valueOf(packagePo.getBrandId().toString()));
        vsProductPo.setSeriesId(Long.valueOf(packagePo.getSeriesId().toString()));
        vsProductPo.setModelId(Long.valueOf(packagePo.getModelId().toString()));
        vsProductPo.setPackageId(Long.valueOf(packagePo.getPackageId().toString()));
        vsProductPo.setOwnerCode(ownerCode);
        vsProductPo.setCompanyCode(ownerCode);
        vsProductPo.setOwnerParCode(ownerCode);
    }

    /**
     * 添加-车辆主数据
     * 整车物料号价格维护
     *
     * @param vo
     * @author：lijun
     * @since：2019-12-17
     */
    @Override
    public Integer saveProductInfo(SaveProductPriceVO vo) {
        logger.debug("添加-车辆主数据，整车主数据维护！--参数vo:{}", vo);
        if (vo == null) {
            throw new ServiceBizException("参数为空，无法进行添加操作！");
        }
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);

        LocalDateTime now = LocalDateTime.now();
        int count;
        if (vo.getProductId() == null) {
            VsProductPO po = new VsProductPO();

            BeanUtils.copyProperties(vo, po);

            po.setAppId(loginInfoDto.getAppId());
            po.setOwnerCode(loginInfoDto.getOwnerCode());
            po.setOwnerParCode(loginInfoDto.getOwnerParCode());
            po.setCompanyCode(loginInfoDto.getCompanyCode());

            po.setEnterDate(LocalDateTime.parse(vo.getEnterDate() + " 00:00:00", DateTimeFormatter.ofPattern(FunctionConstants.FULL_DATE_TIME_FORMAT)));
            po.setExeuntDate(LocalDateTime.parse(vo.getExeuntDate() + " 00:00:00", DateTimeFormatter.ofPattern(FunctionConstants.FULL_DATE_TIME_FORMAT)));

            po.setCreatedBy("-1");
            po.setUpdatedBy("-1");
            po.setCreatedAt(now);
            po.setUpdatedAt(now);
            po.setIsDeleted(0);
            po.setRecordVersion(0);
            count = vsProductMapper.insert(po);
        } else {
            VsProductPO vsProductPo = vsProductMapper.selectById(vo.getProductId());
            if (vsProductPo == null) {
                throw new ServiceBizException("车辆主数据不存在，无法更新");
            }
            BeanUtils.copyProperties(vo, vsProductPo);
            vsProductPo.setUpdatedAt(now);
            vsProductPo.setEnterDate(LocalDateTime.parse(vo.getEnterDate() + " 00:00:00", DateTimeFormatter.ofPattern(FunctionConstants.FULL_DATE_TIME_FORMAT)));
            vsProductPo.setExeuntDate(LocalDateTime.parse(vo.getExeuntDate() + " 00:00:00", DateTimeFormatter.ofPattern(FunctionConstants.FULL_DATE_TIME_FORMAT)));
            count = vsProductMapper.updateById(vsProductPo);
        }

        return count;
    }

    /**
     * 根据公告号从产品中获取最新国补金额,没有为0
     *
     * @author lyz
     * @date 2021/4/16
     */
    public BigDecimal getSubsidyAmount(String noticeNo) {
        if (StrUtil.isNotBlank(noticeNo)) {
            BigDecimal subsidyAmount = vsProductMapper.getSubsidyAmount(noticeNo);
            return ObjectUtil.defaultIfNull(subsidyAmount, BigDecimal.ZERO);
        } else {
            return BigDecimal.ZERO;
        }
    }

    /**
     * 添加-车辆主数据
     * 整车物料号价格维护
     *
     * @param vo
     * @author：zys
     * @since：2020-2-11
     */
    @Override
    public Integer saveProductInfoV2(SaveProductPriceVO vo) {
        logger.debug("添加-车辆主数据，整车主数据维护！--参数vo:{}", vo);
        if (vo == null) {
            throw new ServiceBizException("参数为空，无法进行添加操作！");
        }
        String appId = BasedataCommonConstants.APP_ID_RL;
        LocalDateTime now = LocalDateTime.now();
        int count;
        if (vo.getProductId() == null) {

            QueryWrapper<VsProductPO> queryWrapper = new QueryWrapper<>();
            queryWrapper.lambda().eq(VsProductPO::getProductCode, vo.getProductCode());
            VsProductPO productPo = vsProductMapper.selectOne(queryWrapper);
            if (productPo != null) {
                throw new ServiceBizException("整车编码已存在，请重新维护");
            }
            VsProductPO po = new VsProductPO();
            BeanUtils.copyProperties(vo, po);
            po.setAppId(BasedataCommonConstants.APP_ID_RL);
            po.setDataSources(BasedataDictConstants.DATA_SOURCES_BY_SUPER);
            po.setIsValid(BasedataDictConstants.IS_VALID);
            po.setOwnerCode("-1");
            po.setOwnerParCode("-1");
            po.setCompanyCode("-1");
            po.setStartDate(LocalDateTime.now());
            if (vo.getEnterDate() != null) {
                po.setEnterDate(LocalDateTime.parse(vo.getEnterDate() + " 00:00:00", DateTimeFormatter.ofPattern(FunctionConstants.FULL_DATE_TIME_FORMAT)));
            }
            if (vo.getExeuntDate() != null) {
                po.setExeuntDate(LocalDateTime.parse(vo.getExeuntDate() + " 00:00:00", DateTimeFormatter.ofPattern(FunctionConstants.FULL_DATE_TIME_FORMAT)));
            }
            po.setOrderStatus(BasedataDictConstants.IS_VALID);
            po.setIsIssue(BasedataDictConstants.IS_NO_SEND);
            po.setIsPurchase(BasedataDictConstants.IS_VALID);
            po.setIsSales(BasedataDictConstants.IS_VALID);
            count = vsProductMapper.insert(po);
            //产品ID
            Long productId = po.getProductId();
        } else {
            VsProductPO vsProductPo = vsProductMapper.selectById(vo.getProductId());
            if (vsProductPo == null) {
                throw new ServiceBizException("车辆主数据不存在，无法更新");
            }
            vsProductPo.setBrandId(vo.getBrandId());
            vsProductPo.setSeriesId(vo.getSeriesId());
            vsProductPo.setModelId(vo.getModelId());
            vsProductPo.setPackageId(vo.getPackageId());
            vsProductPo.setOemDirectivePrice(vo.getOemDirectivePrice());
            vsProductPo.setProjectCode(vo.getProjectCode());
            vsProductPo.setSalesVersionName(vo.getSalesVersionName());
            if (vo.getEnterDate() != null) {
                vsProductPo.setEnterDate(LocalDateTime.parse(vo.getEnterDate() + " 00:00:00", DateTimeFormatter.ofPattern(FunctionConstants.FULL_DATE_TIME_FORMAT)));
            }
            if (vo.getExeuntDate() != null) {
                vsProductPo.setExeuntDate(LocalDateTime.parse(vo.getExeuntDate() + " 00:00:00", DateTimeFormatter.ofPattern(FunctionConstants.FULL_DATE_TIME_FORMAT)));
            }
            vsProductPo.setBatteryCode(vo.getBatteryCode());
            vsProductPo.setBatteryVolume(vo.getBatteryVolume());
            vsProductPo.setBatteryOem(vo.getBatteryOem());
            vsProductPo.setPowerCode(vo.getPowerCode());
            vsProductPo.setPowerCodeDesc(vo.getPowerCodeDesc());
            vsProductPo.setPowerMachineBrand(vo.getPowerMachineBrand());
            vsProductPo.setDriveStyleName(vo.getDriveStyleName());
            vsProductPo.setYearModelName(vo.getYearModelName());
            vsProductPo.setMarketName(vo.getMarketName());
            vsProductPo.setProductDesc(vo.getProductDesc());
            vsProductPo.setColorId(vo.getColorId());
            vsProductPo.setColorCode(vo.getColorCode());
            vsProductPo.setColorName(vo.getColorName());
            vsProductPo.setTrimColorId(vo.getTrimColorId());
            vsProductPo.setTrimColor(vo.getTrimColor());
            vsProductPo.setTrimColorName(vo.getTrimColorName());
            vsProductPo.setProductName(vo.getProductName());
            vsProductPo.setUpdatedAt(null);
            count = vsProductMapper.updateById(vsProductPo);
        }
        //清除缓存中产品列表
        String messageFormat = MessageFormat.format(BaseDataCommonConstants.PRODUCT_CACHE_DATA, appId, 0, 6);
        redisClient.del(messageFormat);
        return count;

    }

    @Override
    public List<BrandTreeNewVO> getProductTree1(ProductTreeDTO productTreeDTO) {

        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        //判断缓存中是否有产品列表
        String messageFormat = MessageFormat.format(BaseDataCommonConstants.PRODUCT_CACHE_DATA, loginInfoDto.getAppId(), productTreeDTO.getType(), productTreeDTO.getLevel());
        Object productDto = redisClient.hget(messageFormat, String.valueOf(productTreeDTO.getIsUnlimited()));
        if (null != productDto) {
            return JSONUtil.jsonToList(JSONUtil.objectToJson(productDto), BrandTreeNewVO.class);
        }

        //获取所有数据(到颜色那一级的所有数据)
        List<ProductDataVO> dataList = vsProductMapper.getProductDataNew(loginInfoDto.getAppId(), loginInfoDto.getGroupCode(), loginInfoDto.getOwnerCode());

        String brandId = "";
        String seriesId = "";
        String modelId = "";
        String packageId = "";
        String optionId = "";
        List<OptionTreeVO> optionChildren = new ArrayList<>();
        List<ColorTreeVO> colorChildren = new ArrayList<>();
        List<PackageTreeNewVO> packageChildren = new ArrayList<>();
        List<ModelTreeNewVO> modelChildren = new ArrayList<>();
        List<SeriesTreeNewVO> seriesChildren = new ArrayList<>();
        List<BrandTreeNewVO> brandList = new ArrayList<>();
        for (int i = 0, j = dataList.size(); i < j; i++) {
            ProductDataVO productDataVO = dataList.get(i);
            if (productDataVO == null || productDataVO.getProductId() == null) {
                continue;
            }

            //设置第一级--品牌
            if (!brandId.equals(productDataVO.getBrandId()) && productTreeDTO.getLevel() >= 1) {
                seriesChildren = new ArrayList<>();
                setBrandNew(productDataVO, productTreeDTO.getType(), seriesChildren, brandList,
                        productTreeDTO.getIsUnlimited(), productTreeDTO.getLevel());
                brandId = productDataVO.getBrandId() == null ? "" : productDataVO.getBrandId();
            }

            //设置第二级--车系
            if (!seriesId.equals(productDataVO.getSeriesId()) && productTreeDTO.getLevel() >= 2) {
                modelChildren = new ArrayList<>();
                setSeriesNew(productDataVO, productTreeDTO.getType(), modelChildren, seriesChildren,
                        productTreeDTO.getIsUnlimited(), productTreeDTO.getLevel());
                seriesId = productDataVO.getSeriesId() == null ? "" : productDataVO.getSeriesId();
            }

            //设置第三级--车型
            if (!modelId.equals(productDataVO.getModelId()) && productTreeDTO.getLevel() >= 3) {
                packageChildren = new ArrayList<>();
                setModelNew(productDataVO, productTreeDTO.getType(), packageChildren, modelChildren,
                        productTreeDTO.getIsUnlimited(), productTreeDTO.getLevel());
                modelId = productDataVO.getModelId() == null ? "" : productDataVO.getModelId();
            }

            //设置第四级--配置
            if (!packageId.equals(productDataVO.getPackageId()) && productTreeDTO.getLevel() >= 4) {
                optionChildren = new ArrayList<>();
                setPackageNew(productDataVO, productTreeDTO.getType(), optionChildren, packageChildren,
                        productTreeDTO.getIsUnlimited(), productTreeDTO.getLevel());
                packageId = productDataVO.getPackageId() == null ? "" : productDataVO.getPackageId();
            }

            //设置第五级--选装
            if (!optionId.equals(productDataVO.getOptionId()) && productTreeDTO.getLevel() >= 5) {
                colorChildren = new ArrayList<>();
                setOption(productDataVO, productTreeDTO.getType(), colorChildren, optionChildren,
                        productTreeDTO.getIsUnlimited(), productTreeDTO.getLevel());
                optionId = productDataVO.getOptionId() == null ? "" : productDataVO.getOptionId();
            }

            //设置第六级--产品
            if (productTreeDTO.getLevel() >= 6) {
                setColor1(productDataVO, productTreeDTO.getType(), colorChildren);
            }
        }
        cacheProductNew(brandList, messageFormat, String.valueOf(productTreeDTO.getIsUnlimited()));
        return brandList;

    }

    @Override
    public List<VsProductVO> getAllProductByAppId(String appId) {
        LambdaQueryWrapper<VsProductPO> query = new QueryWrapper<VsProductPO>().lambda().eq(VsProductPO::getAppId
                , appId);
        List<VsProductPO> vsProductPo = this.vsProductMapper.selectList(query);
        return BeanMapperUtil.copyList(vsProductPo, VsProductVO.class);
    }

    /**
     * 查询整车编码信息
     *
     * @param page, productQueryDTO
     * @return com.baomidou.mybatisplus.core.metadata.IPage<com.yonyou.cyxdms.basedata.service.vo.productinfo.VsProductVO>
     * @author caozx
     * @since 2020/12/14
     */
    @Override
    public IPage<VsProductVO> getProductInfo(Page page, ProductQueryDTO productQueryDTO) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);

        if (StrUtil.isNotEmpty(productQueryDTO.getVehicleInfo())) {
            List<String> list = Arrays.asList(productQueryDTO.getVehicleInfo().split(","));
            int listSize = list.size();
            if (listSize >= 1) {
                //品牌
                productQueryDTO.setBrandId(Long.valueOf(list.get(0)));
            }
            if (listSize >= 2) {
                //车系
                productQueryDTO.setSeriesId(Long.valueOf(list.get(1)));
            }
            if (listSize >= 3) {
                //车型
                productQueryDTO.setModelId(Long.valueOf(list.get(2)));
            }
            if (listSize >= 4) {
                //配置
                productQueryDTO.setPackageId(Long.valueOf(list.get(3)));
            }
            if (listSize >= 5) {
                //选装
                productQueryDTO.setOptionId(Long.valueOf(list.get(4)));
            }
            if (listSize >= 6 && !"0".equals(list.get(5))) {
                //颜色
                productQueryDTO.setColorId(Long.valueOf(list.get(5)));
            }
            if (listSize >= 7 && !"0".equals(list.get(6))) {
                //内饰颜色
                productQueryDTO.setTrimColorId(Long.valueOf(list.get(6)));
            }
        }

        Map<String, Object> queryParam = productQueryDTO.toMaps();
        queryParam = setLoginInfoParam(queryParam, loginInfoDto);
        logger.info("查询品牌IPage的queryParam:------------------{}", queryParam);
        /**
         * 产品信息数据放置redis
         */
        String appId = loginInfoDto.getAppId();
        String messageFormat = MessageFormat.format(BaseDataCommonConstants.PRODUCT_CACHE_PRODUCTID, appId);
        Object productData = redisClient.get(messageFormat);
        if (null == productData) {
            LambdaQueryWrapper<VsProductPO> productParam = new QueryWrapper<VsProductPO>().lambda();
            productParam.eq(VsProductPO::getAppId, appId).orderByAsc(VsProductPO::getProductCode, VsProductPO::getIsDeleted);
            List<VsProductPO> productList = vsProductMapper.selectList(productParam);
            List<VsProductVO> productVOList = BeanMapperUtil.copyList(productList, VsProductVO.class);
            redisClient.set(messageFormat, JSONUtil.objectToJson(productVOList), BaseDataCommonConstants.EXPIRE_TIME_ONE_DAY);
        }
        page.setRecords(vsProductMapper.queryVehicleProductInfo(page, queryParam));
        return page;
    }

    /**
     * 查询经销商物料价格
     */
    @Override
    public IPage<VsProductVO> getProductPrice(Page page, ProductQueryDTO productQueryDTO) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);

        if (StrUtil.isNotEmpty(productQueryDTO.getVehicleInfo())) {
            List<String> list = Arrays.asList(productQueryDTO.getVehicleInfo().split(","));
            int listSize = list.size();
//            if (listSize >= 1) {
//                //品牌
//                productQueryDTO.setBrandId(Long.valueOf(list.get(0)));
//            }
            if (listSize >= 1) {
                //车系
                productQueryDTO.setSeriesId(Long.valueOf(list.get(0)));
            }
            if (listSize >= 2) {
                //车型
                productQueryDTO.setModelId(Long.valueOf(list.get(1)));
            }
            if (listSize >= 3) {
                //配置
                productQueryDTO.setPackageId(Long.valueOf(list.get(2)));
            }
            if (listSize >= 4) {
                //选装
                productQueryDTO.setOptionId(Long.valueOf(list.get(3)));
            }
            if (listSize >= 6 && !"0".equals(list.get(5))) {
                //颜色
                productQueryDTO.setColorId(Long.valueOf(list.get(4)));
            }
//            if (listSize >= 6) {
//                //物料编码
//                productQueryDTO.setProductCode(list.get(6));
//            }
//            if (listSize >= 7) {
//                //物料描述
//                productQueryDTO.setProductDesc(list.get(7));
//            }
//            if (listSize >= 8) {
//                //是否可订购
//                productQueryDTO.setOrderStatus(Integer.valueOf(list.get(8)));
//            }
//            if (listSize >= 9) {
//                //是否下发
//                productQueryDTO.setIsIssue(Integer.valueOf(list.get(9)));
//            }


//            if (listSize >= 7 && !list.get(6).equals("0")) {
//                //内饰颜色
//                productQueryDTO.setTrimColorId(Long.valueOf(list.get(6)));
//            }
        }

        Map<String, Object> queryParam = productQueryDTO.toMaps();
        queryParam = setLoginInfoParam(queryParam, loginInfoDto);
        logger.info("查询品牌IPage的queryParam:------------------{}", queryParam);
        /**
         * 产品信息数据放置redis
         */
        String appId = loginInfoDto.getAppId();
        String messageFormat = MessageFormat.format(BaseDataCommonConstants.PRODUCT_CACHE_PRODUCTID, appId);
        Object productData = redisClient.get(messageFormat);
        if (null == productData) {
            LambdaQueryWrapper<VsProductPO> productParam = new QueryWrapper<VsProductPO>().lambda();
            productParam.eq(VsProductPO::getAppId, appId).orderByAsc(VsProductPO::getProductCode, VsProductPO::getIsDeleted);
            List<VsProductPO> productList = vsProductMapper.selectList(productParam);
            List<VsProductVO> productVOList = BeanMapperUtil.copyList(productList, VsProductVO.class);
            redisClient.set(messageFormat, JSONUtil.objectToJson(productVOList), BaseDataCommonConstants.EXPIRE_TIME_ONE_DAY);
        }
        page.setRecords(vsProductMapper.queryVehicleProductPriceInfo(page, queryParam));
        return page;
    }


    @Autowired
    private WholeSalesClient wholeSalesClient;
    /**
     * 查询整车编码信息-已下发
     *
     * @param page, productQueryDTO
     * @return com.baomidou.mybatisplus.core.metadata.IPage<com.yonyou.cyxdms.basedata.service.vo.productinfo.VsProductVO>
     * @author caozx
     * @since 2021/01/13
     */
    @Override
    public IPage<VsProductPriceInfoDealerExcelVO> getProductInfoDealer(Page page, ProductQueryDTO productQueryDTO) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);

        if (StrUtil.isNotEmpty(productQueryDTO.getVehicleInfo())) {
            List<String> list = Arrays.asList(productQueryDTO.getVehicleInfo().split(","));
            int listSize = list.size();
            if (listSize >= 1) {
                //品牌
                productQueryDTO.setBrandId(Long.valueOf(list.get(0)));
            }
            if (listSize >= 2) {
                //车系
                productQueryDTO.setSeriesId(Long.valueOf(list.get(1)));
            }
            if (listSize >= 3) {
                //车型
                productQueryDTO.setModelId(Long.valueOf(list.get(2)));
            }
            if (listSize >= 4) {
                //配置
                productQueryDTO.setPackageId(Long.valueOf(list.get(3)));
            }
            if (listSize >= 5) {
                //选装
                productQueryDTO.setOptionId(Long.valueOf(list.get(4)));
            }
            if (listSize >= 6 && !"0".equals(list.get(5))) {
                //外颜色
                productQueryDTO.setColorId(Long.valueOf(list.get(5)));
            }
            if (listSize >= 7 && !"0".equals(list.get(6))) {
                //内颜色
                productQueryDTO.setTrimColorId(Long.valueOf(list.get(6)));
            }
        }

        Map<String, Object> queryParam = productQueryDTO.toMaps();
        queryParam = setLoginInfoParam(queryParam, loginInfoDto);
        logger.info("查询品牌IPage的queryParam:------------------{}", queryParam);
        List<VsProductPriceInfoDealerExcelVO> records = vsProductMapper.queryVehicleProductInfoDealer(page, queryParam);
        List<String> codeList = records.stream().map(VsProductPriceInfoDealerExcelVO::getProductCode).collect(Collectors.toList());
        List<HasStockDTO> hasStock = wholeSalesClient.getHasStock(codeList).getData();
        Map<String, Integer> hasStockMap = hasStock.stream().collect(Collectors.toMap(HasStockDTO::getProductCode, HasStockDTO::getHasStock, (v1, v2) -> v2));
        for (VsProductPriceInfoDealerExcelVO record : records) {
            record.setHasStock(hasStockMap.getOrDefault(record.getProductCode(),10041002));
        }
        page.setRecords(records);
        return page;
    }

    /**
     * 查询整车编码信息[无分页]
     *
     * @param productQueryDTO
     * @return com.baomidou.mybatisplus.core.metadata.IPage<com.yonyou.cyxdms.basedata.service.vo.productinfo.VsProductVO>
     * @author caozx
     * @since 2020/12/14
     */
    @Override
    public List<VsProductVO> getProductInfoList(VsOptionDTO productQueryDTO) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        Map<String, Object> queryParam = productQueryDTO.toMaps();
        queryParam = setLoginInfoParam(queryParam, loginInfoDto);
        logger.info("查询品牌IPage的queryParam:------------------{}", queryParam);
        /**
         * 产品信息数据放置redis
         */
        String appId = loginInfoDto.getAppId();
        String messageFormat = MessageFormat.format(BaseDataCommonConstants.PRODUCT_CACHE_PRODUCTID, appId);
        Object productData = redisClient.get(messageFormat);
        if (null == productData) {
            LambdaQueryWrapper<VsProductPO> productParam = new QueryWrapper<VsProductPO>().lambda();
            productParam.eq(VsProductPO::getAppId, appId).orderByAsc(VsProductPO::getProductCode, VsProductPO::getIsDeleted);
            List<VsProductPO> productList = vsProductMapper.selectList(productParam);
            List<VsProductVO> productVOList = BeanMapperUtil.copyList(productList, VsProductVO.class);
            redisClient.set(messageFormat, JSONUtil.objectToJson(productVOList), BaseDataCommonConstants.EXPIRE_TIME_ONE_DAY);
        }
        return vsProductMapper.queryVehicleProductInfo(queryParam);
    }

    @Override
    public List<PlanTemplateDTO> getPlanTemplates(List<String> productCodes) {
        return this.vsProductMapper.getPlanTemplates(productCodes);
    }

    /**
     * 设置登录信息传参
     *
     * @param: queryParam
     * @auther: Tansj
     * @since: 2019/11/14
     */
    @Override
    public Map<String, Object> setLoginInfoParam(Map<String, Object> queryParam, LoginInfoDto loginInfoDto) {
        queryParam.put(BasedataCommonConstants.APP_ID, loginInfoDto.getAppId());
        queryParam.put(BasedataCommonConstants.OWNER_CODE, loginInfoDto.getOwnerCode());
        queryParam.put(BasedataCommonConstants.GROUP_CODE, loginInfoDto.getGroupCode());
        queryParam.put(BasedataCommonConstants.ORG_TYPE, loginInfoDto.getOrgType());
        return queryParam;
    }

    /**
     * 下发产品信息
     *
     * @param vsProductVO
     * @return java.lang.Integer
     * @author caozx
     * @since 2020/12/17
     */
    @Override
    public Integer issueProduct(@RequestBody ProductInfosVO vsProductVO) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        String[] ids = vsProductVO.getProductIds().split(",");
        for (int i = 0, j = ids.length; i < j; i++) {
            VsProductPO vsProductPo = vsProductMapper.selectById(ids[i]);
            vsProductPo.setIsIssue(BaseDataDictConstants.IS_VALID);
            vsProductPo.setSendDate(LocalDateTime.now());
            vsProductPo.setSendBy(loginInfoDto.getUserId().toString());
            vsProductMapper.updateById(vsProductPo);
        }
        return 1;
    }

    /**
     * 产品信息是否可订购
     *
     * @param vsProductVO * @return java.lang.Integer
     * @author caozx
     * @since 2020/12/17
     */
    @Override
    public Integer updateOrderStatus(@RequestBody ProductInfosVO vsProductVO) {
        String[] ids = vsProductVO.getProductIds().split(",");
        for (int i = 0, j = ids.length; i < j; i++) {
            VsProductPO vsProductPo = vsProductMapper.selectById(ids[i]);
            vsProductPo.setOrderStatus(vsProductVO.getOrderStatus());
            vsProductMapper.updateById(vsProductPo);
        }
        return 1;
    }

    /**
     * 整车编码信息导出
     *
     * @return void
     * @author caozx
     * @since 2020/12/17
     */
    @Override
    public void exportProducts(HttpServletResponse response,ProductQueryDTO dto) {

        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);

        Map<String, Object> queryParam = dto.toMaps();
        queryParam = setLoginInfoParam(queryParam, loginInfoDto);
        List<VsProductInfoExcelVO> res = vsProductMapper.excelOem(queryParam);
        try {
            EasyPoiUtil.exportExcelResponse("整车物料查看", null, res, VsProductInfoExcelVO.class, "整车物料查看.xls", response);
        } catch (IOException e) {
            throw new ServiceBizException("文件导出失败！");
        }

    }

    @Override
    public CmsApp04 searchCmsApp04Data(CmsApp04QueryDto cmsApp04QueryDto) {
        String recoedTime = cmsApp04QueryDto.getRecordTime();

        if (!StringUtils.isNullOrEmpty(recoedTime)) {
            Long time = Long.parseLong(recoedTime);
            LocalDateTime longToLocalDateTime =
                    LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault());
            cmsApp04QueryDto.setLastTime(dateToString(longToLocalDateTime));

        }
        List<CmsApp04Data> list = vsProductMapper.searchCmsApp04Data(cmsApp04QueryDto);
        CmsApp04 cmsApp04 = new CmsApp04();
        cmsApp04.setRequestId(cmsApp04QueryDto.getRequestId());
        cmsApp04.setList(list);
        if (CollectionUtils.isNotEmpty(list)) {
            CmsApp04Data cmsApp04Data = list.get(0);
            if (cmsApp04Data != null && cmsApp04Data.getUpdatedAt() != null) {

                Long recoedTimeLast = cmsApp04Data.getUpdatedAt().toInstant(ZoneOffset.of("+8")).toEpochMilli();
                cmsApp04.setRecordTime(recoedTimeLast);
            }

        }
        return cmsApp04;

    }

    private String dateToString(LocalDateTime localDateTime) {
        if (localDateTime == null) {
            return "";
        }
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        return df.format(localDateTime);
    }

    /**
     * 新能源SAP-更新销售指导价
     *
     * @param cms008ReqDTO
     * @return java.lang.Integer
     * @author caozx
     * @since 2021/01/21
     */
    @Override
    public Integer sapUpdateProductPirce(CMS008ReqDTO cms008ReqDTO) {
//        List<DTCMS008RET.ROW> rowlist = new ArrayList<>();
//        LambdaQueryWrapper<VsProductPO> query = new QueryWrapper<VsProductPO>().lambda();
//        query.eq(VsProductPO::getProductCode, cms008ReqDTO.getProductCode());
//        List<VsProductPO> vsProductPOS = vsProductMapper.selectList(query);
//        if (vsProductPOS.size() != 0) {
//            CMS008PO cms008PO = new CMS008PO();
//            BeanUtil.copyProperties(cms008ReqDTO, cms008PO);
//            productPriceDataMapper.insert(cms008PO);
//            Date startDate = cms008PO.getStartDate();
//            Date endDate = cms008PO.getEndDate();
//            Date now = new Date();
//            if (now.after(startDate) && now.before(endDate)) {
//                String strBasicPrice = StrUtil.trim(cms008PO.getBasicPrice());
//                String strInOutPrice = StrUtil.trim(cms008PO.getInOutPrice());
//                BigDecimal basicPrice = new BigDecimal(StrUtil.isBlank(strBasicPrice) ? "0" : strBasicPrice);
//                BigDecimal inOutPrice = new BigDecimal(StrUtil.isBlank(strInOutPrice) ? "0" : strInOutPrice);
//                vsProductMapper.updateOemDirectivePriceByProductCode(cms008PO.getProductCode(), basicPrice.add(inOutPrice));
//            }
//            rowlist.add(addcms008Row(cms008ReqDTO, null));
//        } else {
//            rowlist.add(addcms008Row(cms008ReqDTO, "物料编码  " + cms008ReqDTO.getProductCode() + " 在系统中不存在!"));
//        }
//        logger.info("新能源SAP-更新销售指导价:{}", cms008ReqDTO);
//        DTCMS008RET cms008 = new DTCMS008RET();
//        cms008.setROW(rowlist);
//        Cms008ObjectFactory objectFactory = new Cms008ObjectFactory();
//        Boolean result = true ;//wsVehicleService.call("cms008", objectFactory.createMTCMS008RET(cms008));
//        Assert.isTrue(result, "[{}]cms008-SAP回调", LocalDateTime.now());
//        logger.info("cms008-SAP回调:{}", result);
        return 1;
    }

    /**
     * 股份SAP-更新销售指导价
     *
     * @param cmsvhcl003ReqDTO
     * @return java.lang.Integer
     * @author caozx
     * @since 2021/02/05
     */
    @Override
    public Integer sapSharesUpdateProductPirce(CMSVHCL003ReqDTO cmsvhcl003ReqDTO) {
//        // 整车指导价 ZA00
//        if (StrUtil.equalsIgnoreCase(cmsvhcl003ReqDTO.getConditionType(), "ZA00")) {
//            // 北销1080 株销1180
//            if (StrUtil.equalsIgnoreCase(cmsvhcl003ReqDTO.getSalesOrg(), "1080") || StrUtil.equalsIgnoreCase(cmsvhcl003ReqDTO.getSalesOrg(), "1180")) {
//                // 分销10 直销20
//                if (StrUtil.equalsIgnoreCase(cmsvhcl003ReqDTO.getDistributeChannel(), "10")) {
//
//                    LambdaQueryWrapper<VsOptionPO> query = new QueryWrapper<VsOptionPO>().lambda();
//                    query.eq(VsOptionPO::getOptionCode, cmsvhcl003ReqDTO.getVariant());
//                    List<VsOptionPO> vsOptionPOS = vsOptionMapper.selectList(query);
//                    if (vsOptionPOS.size() != 0) {
//                        CMSVHCL003PO cmsvhcl003PO = new CMSVHCL003PO();
//                        BeanUtils.copyProperties(cmsvhcl003ReqDTO, cmsvhcl003PO);
//                        fuelPriceInfoMapper.insert(cmsvhcl003PO);
//                        Date startDate = cmsvhcl003PO.getStartDate();
//                        Date endDate = cmsvhcl003PO.getEndDate();
//                        Date now = new Date();
//                        if (now.after(startDate) && now.before(endDate)) {
//                            String strAmount = StrUtil.trim(cmsvhcl003PO.getAmount());
//                            BigDecimal amount = new BigDecimal(StrUtil.isBlank(strAmount) ? "0" : strAmount);
//                            /* 更新油市场指导价 **/
//                            vsProductMapper.updateOemDirectivePriceByProductCodeOil1(cmsvhcl003PO.getVariant(), amount);
//                            /* 更新电共平台车市场指导价 **/
//                            vsProductMapper.updateOemDirectivePriceByProductCodeOil2(cmsvhcl003PO.getVariant(), amount);
//                        }
//                    }
//                }
//            }
//        }
        return 1;
    }

    ;

    /**
     * SAP-批量更新销售指导价(油/电)
     *
     * @param
     * @return java.lang.Integer
     * @author caozx
     * @since 2021/02/07
     */
    @Override
    public Boolean sapSharesbatchUpdateProductPirce() {
        vsProductMapper.batchUpdateProductSharesPirce();
        vsProductMapper.batchUpdateProductPirce();
        return true;
    }

    /**
     * 自动任务根据公告号更新国补金额
     *
     * @author lyz
     * @date 2021/4/20
     */
    @Override
    public void updateSubsidyAmount() {
        cms009Mapper.updateSubsidyAmount();
    }

    @Override
    public IPage<TtVsPlanTemplateDTO> queryCarListSideC(Page<TtVsPlanTemplateDTO> page, TtVsPlanTemplateDTO dto) {
        return vsProductMapper.queryCarListSideC(page,dto);
    }

    @Override
    public List<TtVsPlanTemplateDTO> queryPlan1DetailProductInfo(List<String> dtos) {
        return vsProductMapper.queryPlan1DetailProductInfo(dtos);
    }

    @Override
    public void excelOem(ProductQueryDTO dto, HttpServletResponse response) {

    }

    @Override
    public void exportProductsPrice(HttpServletResponse response,ProductQueryDTO dto) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        Map<String, Object> queryParam = dto.toMaps();
        queryParam = setLoginInfoParam(queryParam, loginInfoDto);
        logger.info("查询品牌IPage的queryParam:------------------{}", queryParam);
        List<VsProductPriceInfoExcelVO> res = vsProductMapper.excelPriceOem(queryParam);
        for (int i = 0; i < res.size(); i++) {
            res.get(i).setNo(i+1);
        }
        try {
            EasyPoiUtil.exportExcelResponse("整车物料价格查询", null, res, VsProductPriceInfoExcelVO.class, "整车物料价格查询.xls", response);
        } catch (IOException e) {
            throw new ServiceBizException("文件导出失败！");
        }
    }

    @Override
    public void exportTemplate(HttpServletResponse response) {
        String sheetName = "整车物料导入模板";
        String titleName = "整车物料导入模板";
        List<VsProductExcelTemplateVO> vsProductExcelTemplateVoS = vsProductMapper.excelOemOn();
        try {
            EasyPoiUtil.exportExcelResponse(sheetName, titleName, vsProductExcelTemplateVoS, VsProductExcelTemplateVO.class, "整车物料导入模板.xls", response);
        } catch (IOException e) {
            throw new ServiceBizException("文件导出失败！");
        }
    }

    @Override
    public Map<String, List<ExportMsgVO>> checkImportList(List<SaveImportExcelVO> list,  Integer titleRows, Integer headerRows) {
        List<SaveImportExcelVO> listResult = new ArrayList<>() ;
        for (SaveImportExcelVO saveImportExcelVO : list) {
            if (!StringUtils.isBlank(saveImportExcelVO.getProductCode())){
                listResult.add(saveImportExcelVO);
            }
        }



        List<ExportMsgVO> errs = new ArrayList<>();
        if (listResult.isEmpty()) {
            ExportMsgVO exportMsgVO = new ExportMsgVO();
            exportMsgVO.setRowNO(0);
            exportMsgVO.setErrorMsg("未导入任何数据!");
            errs.add(exportMsgVO);
        } else {
            for (int i = 0; i < listResult.size(); i++) {
                try {
                    checkImportOne(listResult.get(i));
                } catch (Exception e) {
                    logger.info(e.getMessage(), e);
                    ExportMsgVO err = new ExportMsgVO();
                    err.setRowNO(i + 1 + titleRows + headerRows);
                    err.setErrorMsg(e.getMessage());
                    errs.add(err);
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    break;
                }
            }
        }
        if (CollectionUtil.isNotEmpty(errs)) {
            Map<String, List<ExportMsgVO>> errorMap = new HashMap<>(16);
            errorMap.put("errorList", errs);
            return errorMap;
        } else {
            return null;
        }
    }

    @Override
    public void sapInsertInterface(TiProductPriceDataVO vo) {
        vsProductMapper.sapInsertInterface(vo);
    }

    @Override
    public void updateProductPrice(VsProductDTO dto) {
        vsProductMapper.updateProductPrice(dto);
    }

    @Override
    public List<TiProductPriceDataVO> queryProductPriceLog(Integer type) {
        return vsProductMapper.queryProductPriceLog(type);
    }

    @Override
    public void updateProductPriceLog(TiProductPriceDataVO vo) {
        vsProductMapper.updateProductPriceLog(vo);
    }

    @Override
    public void exportInfoDealer(Page<VsProductPriceInfoDealerExcelVO> page, ProductQueryDTO dto,HttpServletResponse response) {
        List<VsProductPriceInfoDealerExcelVO> res = getProductInfoDealer(page, dto).getRecords();
        for (int i = 0; i < res.size(); i++) {
            res.get(i).setNo(i+1);
        }
        try {
            EasyPoiUtil.exportExcelResponse("整车物料价格查询", null, res, VsProductPriceInfoDealerExcelVO.class, "整车物料价格查询.xls", response);
        } catch (IOException e) {
            throw new ServiceBizException("文件导出失败！");
        }
    }


    private void checkImportOne(SaveImportExcelVO saveImportExcelVO) {
        Double oemDirectivePrice = saveImportExcelVO.getOemDirectivePrice();
        String orderStatus = saveImportExcelVO.getOrderStatus();
        String productCode = saveImportExcelVO.getProductCode();
        VsProductPO vsProductPO = vsProductMapper.selectByProductCode(productCode);
        if (vsProductPO==null){
            throw new RuntimeException("产品不存在");
        }
        if ("是".equals(orderStatus)) {
            vsProductPO.setOrderStatus(10041001);

        }
        if ("否".equals(orderStatus)) {
            vsProductPO.setOrderStatus(10041002);

        }
        vsProductPO.setOemDirectivePrice(oemDirectivePrice);
        vsProductMapper.updateById(vsProductPO);
    }


    /**
     * 获取cms008错误信息
     *
     * @param dto, errMsg
     * @return com.baic.cms.ws.vehicle.client.dto.cms008.DTCMS008RET.ROW.ITEM
     * @author caozx
     * @since 2021/01/26
     */
//    public DTCMS008RET.ROW addcms008Row(CMS008ReqDTO dto, String errMsg) {
//
//        DTHEADER header = new DTHEADER();
//        header.setSENDER("CMS");
//        header.setRECEIVER("SAP");
//        header.setDTSEND(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").format(LocalDateTime.now()));
//        header.setINTFID(dto.getIntfid());
//        header.setMSGID(dto.getMsgid());
//
//        DTCMS008RET.ROW.ITEM item = new DTCMS008RET.ROW.ITEM();
//        item.setMATNR(dto.getProductCode());
//        item.setZCXBM(dto.getModelCcode());
//        if (StrUtil.isBlank(errMsg)) {
//            item.setZSTATUS("S");
//        } else {
//            item.setZSTATUS("E");
//            item.setZMESSAGE(errMsg);
//        }
//
//        DTCMS008RET.ROW row = new DTCMS008RET.ROW();
//        row.setHEADER(header);
//        row.setITEM(item);
//        return row;
//    }

    /**
     * 新能源SAP-更新国补金额
     *
     * @param cms009ReqDTO
     * @return java.lang.Integer
     * @author caozx
     * @since 2021/01/21
     */
    @Override
    public Integer sapUpdateProductSubsidies(CMS009ReqDTO cms009ReqDTO) {
//        List<DTCMS009RET.ROW> rowlist = new ArrayList<>();
//
//        /* 插入补贴信息 **/
//        CMS009PO cms009PO = new CMS009PO();
//        BeanUtil.copyProperties(cms009ReqDTO, cms009PO);
//        cms009Mapper.insert(cms009PO);
//        /* 根据补贴信息更新国补金额 **/
//        updateSubsidyAmount();
//        logger.info("新能源SAP-更新国补金额:{}", cms009ReqDTO);
//        rowlist.add(addcms009Row(cms009ReqDTO, null));
//        DTCMS009RET cms009 = new DTCMS009RET();
//        cms009.setROW(rowlist);
//        Cms009ObjectFactory objectFactory = new Cms009ObjectFactory();
//        Boolean result = true;//wsVehicleService.call("cms009", objectFactory.createMTCMS009RET(cms009));
//        Assert.isTrue(result, "[{}]cms009-SAP回调", LocalDateTime.now());
//        logger.info("cms009-SAP回调:{}", result);
        return 1;

    }

    /**
     * 获取cms009错误信息
     *
     * @param dto, errMsg
     * @return com.baic.cms.ws.vehicle.client.dto.cms009.DTCMS009RET.ROW
     * @author caozx
     * @since 2021/01/26
     */
//    public DTCMS009RET.ROW addcms009Row(CMS009ReqDTO dto, String errMsg) {
//
//        DTCMS009RET.ROW row = new DTCMS009RET.ROW();
//        row.setSENDER("CMS");
//        row.setRECEIVER("SAP");
//        row.setDTSEND(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").format(LocalDateTime.now()));
//        row.setMSGID(dto.getMsgid());
//        row.setZGGH(dto.getNoticeNo());
//        row.setZBTTYP(dto.getSubsidyAmount());
//        row.setZSF(dto.getProvince());
//        row.setZDQ(dto.getCity());
//        if (StrUtil.isBlank(errMsg)) {
//            row.setZSTATUSTR("S");
//        } else {
//            row.setZSTATUSTR("E");
//            row.setZSTATUSTXT(errMsg);
//        }
//        return row;
//    }

    /**
     * 获取产品信息
     *
     * @param productCode
     * @return com.yonyou.cyxdms.basedata.service.vo.productinfo.VsProductVO
     * @author caozx
     * @since 2021/01/28
     */
    @Override
    public VsProductVO getProduct(String productCode) {
        LambdaQueryWrapper<VsProductPO> query = new QueryWrapper<VsProductPO>().lambda();
        query.eq(VsProductPO::getProductCode, productCode);
        VsProductPO vsProductPo = vsProductMapper.selectOne(query);
        VsProductVO vsProductVO = new VsProductVO();

        LambdaQueryWrapper<SeriesPO> seriesQuery = new QueryWrapper<SeriesPO>().lambda();
        seriesQuery.eq(SeriesPO::getSeriesId, vsProductPo.getSeriesId());
        SeriesPO seriesPo = seriesMapper.selectOne(seriesQuery);
        BeanUtils.copyProperties(vsProductPo,vsProductVO);
        vsProductVO.setPowerType(String.valueOf(seriesPo.getPowerType()));

        return vsProductVO;
    }

    /**
     * 导入列表数据
     *
     * @param list
     * @param titleRows
     * @param headerRows
     * @author lyz
     * @date 2021/3/22
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, List<ExportMsgVO>> checkSaveImportList(List<SaveProductPriceImportVO> list, Integer titleRows, Integer headerRows) {
        List<ExportMsgVO> errs = new ArrayList<>();
        if (list.isEmpty()) {
            ExportMsgVO exportMsgVO = new ExportMsgVO();
            exportMsgVO.setRowNO(0);
            exportMsgVO.setErrorMsg("未导入任何数据!");
            errs.add(exportMsgVO);
        } else {
            for (int i = 0; i < list.size(); i++) {
                try {
                    checkSaveImportOne(list.get(i));
                } catch (Exception e) {
                    logger.info(e.getMessage(), e);
                    ExportMsgVO err = new ExportMsgVO();
                    err.setRowNO(i + 1 + titleRows + headerRows);
                    err.setErrorMsg(e.getMessage());
                    errs.add(err);
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    break;
                }
            }
        }
        if (CollectionUtil.isNotEmpty(errs)) {
            Map<String, List<ExportMsgVO>> errorMap = new HashMap<>(16);
            errorMap.put("errorList", errs);
            return errorMap;
        } else {
            return null;
        }
    }

    /**
     * 导入单条数据
     *
     * @param vo 导入数据
     * @author lyz
     * @date 2021/3/22
     */
    private void checkSaveImportOne(SaveProductPriceImportVO vo) {
        LoginInfoDto loginInfoDto = ApplicationContextHelper.getBeanByType(LoginInfoDto.class);
        /* 参数去除前后多余空格 **/
        vo.setBrandName(StrUtil.trimToEmpty(vo.getBrandName()));
        vo.setSeriesCode(StrUtil.trimToEmpty(vo.getSeriesCode()));
        vo.setProductCode(StrUtil.trimToEmpty(vo.getProductCode()));
        vo.setProductName(StrUtil.trimToEmpty(vo.getProductName()));
        vo.setOptionCode(StrUtil.trimToEmpty(vo.getOptionCode()));
        vo.setOptionName(StrUtil.trimToEmpty(vo.getOptionName()));
        vo.setConfigCode(StrUtil.trimToEmpty(vo.getConfigCode()));
        vo.setConfigName(StrUtil.trimToEmpty(vo.getConfigName()));
        vo.setModelCode(StrUtil.trimToEmpty(vo.getModelCode()));
        vo.setModelName(StrUtil.trimToEmpty(vo.getModelName()));
        vo.setTrimCode(StrUtil.trimToEmpty(vo.getTrimCode()));
        vo.setTrimName(StrUtil.trimToEmpty(vo.getTrimName()));
        vo.setColorCode(StrUtil.trimToEmpty(vo.getColorCode()));
        vo.setColorName(StrUtil.trimToEmpty(vo.getColorName()));
        vo.setNoticeNo(StrUtil.trimToEmpty(vo.getNoticeNo()));
        /* 必填校验 **/
//        Assert.notBlank(vo.getBrandName(), "品牌名称必填");
//        Assert.notBlank(vo.getSeriesCode(), "车系代码必填");
//        Assert.notBlank(vo.getProductCode(), "整编代码必填");
//        Assert.notBlank(vo.getProductName(), "整编名称必填");
//        Assert.notBlank(vo.getOptionCode(), "选装代码必填");
//        Assert.notBlank(vo.getOptionName(), "选装名称必填");
//        Assert.notBlank(vo.getConfigCode(), "配置编码必填");
//        Assert.notBlank(vo.getConfigName(), "配置名称必填");
//        Assert.notBlank(vo.getModelCode(), "车型代码必填");
//        Assert.notBlank(vo.getModelName(), "车型名称必填");
//        Assert.notBlank(vo.getTrimCode(), "内饰代码必填");
//        Assert.notBlank(vo.getTrimName(), "内饰描述必填");
//        Assert.notBlank(vo.getColorCode(), "外饰代码必填");
//        Assert.notBlank(vo.getColorName(), "外饰描述必填");
//        Assert.notBlank(vo.getNoticeNo(), "公告号必填");

        VsProductPO po = new VsProductPO();
        /* 产品校验 **/
        LambdaQueryWrapper<VsProductPO> productQuery = new LambdaQueryWrapper<>();
        productQuery.eq(VsProductPO::getAppId, loginInfoDto.getAppId())
                .eq(VsProductPO::getProductCode, vo.getProductCode());
        VsProductPO product = vsProductMapper.selectOne(productQuery);
        if (null != product) {
            po = product;
        }
        /* 品牌校验 **/
        LambdaQueryWrapper<BrandPO> queryBrand = new LambdaQueryWrapper<>();
        queryBrand.eq(BrandPO::getBrandName, vo.getBrandName());
        queryBrand.eq(BrandPO::getAppId, loginInfoDto.getAppId());
        List<BrandPO> brandList = brandService.list(queryBrand);
//        Assert.isTrue(brandList.size() <= 1, "存在相同品牌{}数据", vo.getBrandName());
        BrandPO brandPo = CollectionUtil.getFirst(brandList);
//        Assert.isTrue(brandPo != null, "品牌名称{}获取品牌失败", vo.getBrandName());
        po.setBrandId(brandPo.getBrandId());
        /* 车系校验 **/
        SeriesDictVO seriesDictVO = seriesMapper.getByCodeOnly(loginInfoDto.getAppId(), vo.getSeriesCode());
//        Assert.isTrue(seriesDictVO != null, "车系代码{}获取车系失败", vo.getSeriesCode());
//        Assert.isTrue(ObjectUtil.equal(seriesDictVO.getBrandId().longValue(), po.getBrandId()), "车系代码{}对应品牌不匹配", vo.getSeriesCode());
        po.setSeriesId(seriesDictVO.getSeriesId().longValue());
        /* 车型校验 **/
        ModelDictVO modelDictVO = modelMapper.getByCodeOnly(loginInfoDto.getAppId(), vo.getModelCode());
        if (null == modelDictVO) {
            ModelPO modelPo = new ModelPO();
            modelPo.setIsValid(BasedataDictConstants.IS_VALID);
            modelPo.setBrandId(po.getBrandId());
            modelPo.setSeriesId(po.getSeriesId());
            modelPo.setModelCode(vo.getModelCode());
            modelPo.setModelName(vo.getModelName());
            modelMapper.insert(modelPo);
            po.setModelId(modelPo.getModelId());
        } else {
//            Assert.isTrue(ObjectUtil.equal(modelDictVO.getSeriesId(), po.getSeriesId()), "车型代码{}对应车系不匹配", vo.getModelCode());
            if (!ObjectUtil.equal(vo.getModelName(), modelDictVO.getModelName())) {
                ModelPO modelPo = modelMapper.selectById(modelDictVO.getModelId());
                modelPo.setModelName(modelDictVO.getModelName());
                modelPo.setUpdatedAt(null);
                modelPo.setUpdatedBy(null);
                modelMapper.updateById(modelPo);
            }
            po.setModelId(modelDictVO.getModelId());
        }
        /* 配置校验 **/
        PackageDictVO packageDictVO = packageMapper.getByCodeOnly(loginInfoDto.getAppId(), vo.getConfigCode());
        if (null == packageDictVO) {
            PackagePO packagePo = new PackagePO();
            packagePo.setIsValid(BasedataDictConstants.IS_VALID);
            packagePo.setBrandId(po.getBrandId());
            packagePo.setSeriesId(po.getSeriesId());
            packagePo.setModelId(po.getModelId());
            packagePo.setConfigCode(vo.getConfigCode());
            packagePo.setConfigName(vo.getConfigName());
            packageMapper.insert(packagePo);
            po.setPackageId(packagePo.getPackageId());
        } else {
//            Assert.isTrue(ObjectUtil.equal(packageDictVO.getModelId().longValue(), po.getModelId()), "配置代码{}对应车型不匹配", vo.getConfigCode());
            if (!ObjectUtil.equal(vo.getConfigName(), packageDictVO.getConfigName())) {
                PackagePO packagePo = packageMapper.selectById(packageDictVO.getPackageId().longValue());
                packagePo.setConfigName(vo.getConfigName());
                packagePo.setUpdatedAt(null);
                packagePo.setUpdatedBy(null);
                packageMapper.updateById(packagePo);
            }
            po.setPackageId(packageDictVO.getPackageId().longValue());
        }
        /* 选装校验 **/
        LambdaQueryWrapper<VsOptionPO> optionWapper = new LambdaQueryWrapper<>();
        optionWapper.eq(VsOptionPO::getAppId, loginInfoDto.getAppId())
                .eq(VsOptionPO::getOptionCode, vo.getOptionCode());
        List<VsOptionPO> list = vsOptionService.list(optionWapper);
//        Assert.isTrue(list.size() <= 1, "存在相同选装代码{}数据", vo.getOptionCode());
        VsOptionPO vsOptionPo = CollectionUtil.getFirst(list);
        if (null == vsOptionPo) {
            VsOptionPO optionPo = new VsOptionPO();
            optionPo.setIsValid(BasedataDictConstants.IS_VALID);
            optionPo.setPackageId(po.getPackageId());
            optionPo.setOptionCode(vo.getOptionCode());
            optionPo.setOptionName(vo.getOptionName());
            optionMapper.insert(optionPo);
            po.setOptionId(optionPo.getOptionId());
        } else {
//            Assert.isTrue(ObjectUtil.equal(vsOptionPo.getPackageId(), po.getPackageId()), "选装代码{}对应配置不匹配", vo.getOptionCode());
            if (!ObjectUtil.equal(vo.getOptionName(), vsOptionPo.getOptionName())) {
                VsOptionPO optionPo = optionMapper.selectById(vsOptionPo.getOptionId());
                optionPo.setOptionName(vo.getOptionName());
                optionPo.setUpdatedAt(null);
                optionPo.setUpdatedBy(null);
                optionMapper.updateById(optionPo);
            }
            po.setOptionId(vsOptionPo.getOptionId());
        }
        /* 外饰 **/
        ColorPO colorVO = colorMapper.getByCode(loginInfoDto.getAppId(), vo.getColorCode());
        if (null == colorVO) {
            ColorPO colorPo = new ColorPO();
            colorPo.setIsValid(BasedataDictConstants.IS_VALID);
            colorPo.setColorCode(vo.getColorCode());
            colorPo.setColorType(BasedataDictConstants.EXTERIOR_COLOR);
            colorPo.setColorName(vo.getColorName());
            colorMapper.insert(colorPo);
            po.setColorId(colorPo.getColorId().longValue());
        } else {
            if (!ObjectUtil.equal(vo.getColorName(), colorVO.getColorName())) {
                ColorPO colorPo = colorMapper.selectById(colorVO.getColorId());
                colorPo.setColorName(vo.getColorName());
                colorPo.setUpdatedAt(null);
                colorPo.setUpdatedBy(null);
                colorMapper.updateById(colorPo);
            }
            po.setColorId(colorVO.getColorId().longValue());
        }
        /* 内饰 **/
        ColorPO trimVO = colorMapper.getByCode(loginInfoDto.getAppId(), vo.getTrimCode());
        if (null == trimVO) {
            ColorPO colorPo = new ColorPO();
            colorPo.setIsValid(BasedataDictConstants.IS_VALID);
            colorPo.setColorCode(vo.getTrimCode());
            colorPo.setColorType(BasedataDictConstants.INTERIOR_COLOR);
            colorPo.setColorName(vo.getTrimName());
            colorMapper.insert(colorPo);
            po.setTrimColorId(colorPo.getColorId().longValue());
            po.setTrimColor(colorPo.getColorId().toString());
        } else {
            if (!ObjectUtil.equal(vo.getTrimName(), trimVO.getColorCode())) {
                ColorPO colorPo = colorMapper.selectById(trimVO.getColorId());
                colorPo.setColorName(vo.getTrimName());
                colorPo.setUpdatedAt(null);
                colorPo.setUpdatedBy(null);
                colorMapper.updateById(colorPo);
            }
            po.setTrimColorId(trimVO.getColorId().longValue());
            po.setTrimColor(trimVO.getColorId().toString());
        }
        /* 其余字段赋值 **/
        BigDecimal subsidyAmount = getSubsidyAmount(vo.getNoticeNo());
        po.setProductCode(vo.getProductCode());
        po.setProductName(vo.getProductName());
        po.setDataSources(BasedataDictConstants.DATA_SOURCES_BY_SUPER);
        po.setIsPurchase(BasedataDictConstants.IS_VALID);
        po.setIsSales(BasedataDictConstants.IS_VALID);
        po.setProductStatus(14081001);
        po.setIsValid(BasedataDictConstants.IS_VALID);
        po.setNoticeNo(vo.getNoticeNo());
        po.setSubsidyAmount(subsidyAmount);
        if (null == po.getStartDate()) {
            po.setStartDate(LocalDateTime.now());
        }
        if (null == po.getOrderStatus()) {
            po.setOrderStatus(BasedataDictConstants.IS_VALID);
        }
        if (po.getProductId() == null) {
            save(po);
            VsProductOptionPO vProductOptionPo = new VsProductOptionPO();
            vProductOptionPo.setAppId(loginInfoDto.getAppId());
            vProductOptionPo.setCompanyCode(loginInfoDto.getCompanyCode());
            vProductOptionPo.setOwnerCode(loginInfoDto.getOwnerCode());
            vProductOptionPo.setOwnerParCode(loginInfoDto.getOwnerParCode());
            vProductOptionPo.setIsDeleted(0);
            vProductOptionPo.setRecordVersion(0);
            vProductOptionPo.setCreatedBy("-1");
            vProductOptionPo.setUpdatedBy("-1");
            vProductOptionPo.setCreatedAt(LocalDateTime.now());
            vProductOptionPo.setUpdatedAt(LocalDateTime.now());
            vProductOptionPo.setOptionId(po.getOptionId());
            vProductOptionPo.setProductId(po.getProductId());
            vsProductOptionMapper.insert(vProductOptionPo);
        } else {
            po.setUpdatedAt(null);
            po.setUpdatedBy(null);
            updateById(po);
            Map<String, Object> map = vsProductOptionMapper.selectByProductId(po.getProductId());
            VsProductOptionPO vsProductOptionPo = new VsProductOptionPO();
            vsProductOptionPo.setProductOptionId(Long.valueOf(map.get("productOptionId").toString()));
            vsProductOptionPo.setProductId(po.getProductId());
            vsProductOptionPo.setOptionId(vo.getOptionId());
            vsProductOptionPo.setUpdatedAt(LocalDateTime.now());
            vsProductOptionPo.setUpdatedBy(loginInfoDto.getUserId().toString());
            vsProductOptionPo.setCreatedBy(loginInfoDto.getUserId().toString());
            vsProductOptionPo.setCreatedAt(LocalDateTime.now());
            vsProductOptionPo.setIsDeleted(0);
            vsProductOptionPo.setRecordVersion(0);
            vsProductOptionPo.setAppId(loginInfoDto.getAppId());
            vsProductOptionPo.setCompanyCode(loginInfoDto.getCompanyCode());
            vsProductOptionPo.setOwnerCode(loginInfoDto.getOwnerCode());
            vsProductOptionPo.setOwnerParCode(loginInfoDto.getOwnerParCode());
            vsProductOptionMapper.updateById(vsProductOptionPo);
        }
        logger.info("产品{}已处理", vo.getProductCode());
    }

    @Override
    public VsProductDlrVO getProductNew(String productCode) {
        return vsProductMapper.getProductNew(productCode);
    }

}
